#java #xml #jackson #pmd
Вопрос:
Я пытаюсь десериализовать вывод PMD с помощью Jackson. В частности, я хочу получить список нарушений и их данные, которые PMD предоставляет мне в следующей форме:
<pmd-cpd>
<duplication lines="615" tokens="1188">
<file line="126" path="SomePathHere"/>
<file line="126" path="SomePathHere"/>
<codefragment>
<![CDATA[
SomeCodeFragmentHere
]]>
</codefragment>
</duplication>
MoreDuplications
</pmd-cpd>
В настоящее время у меня есть следующие классы для десериализации:
public class PmdResults {
@JacksonXmlProperty(localName = "duplication")
List<CodeClone> codeClones;
}
public class CodeClone {
public int lines;
public int tokens;
@JacksonXmlProperty(localName = "file")
public List<SourceFile> files;
public CodeClone() { super(); }
public static class SourceFile {
public int line;
public String path;
}
}
В настоящее время Jackson может десериализовать корень и оба «строки» и «токены» правильно. Однако, вместо того, чтобы пытаться десериализовать два элемента «file» в объекты SourceFile, он ищет непосредственно атрибут «line» для десериализации атрибутов этих элементов. Я также не уверен, как заставить Jackson игнорировать элемент «codefragment», учитывая, что мне на самом деле не нужна эта информация. Я был бы очень благодарен за любую помощь в этом отношении, поскольку мне немного сложно понять, почему он смог определить, что дублирующие элементы должны становиться объектами в списке, но не элементами файла, которые, похоже, соответствуют тому же формату.
PS.: На самом деле я бы предпочел вообще избавиться от класса PmdResults и напрямую десериализовать список<CodeClone> , но я также не смог найти какой-либо способ сделать это.
Ответ №1:
В вашем Java-коде есть два типа проблем:
В вашем Java-коде у вас есть свойства типа List<...>
@JacksonXmlProperty(localName = "duplication")
List<CodeClone> codeClones;
и
@JacksonXmlProperty(localName = "file")
List<SourceFiles> files;
Вам также нужно аннотировать эти List
свойства
с @JacksonXmlWrapper(useWrapping = false)
помощью .
Если вы опустите это, то по умолчанию будет useWrapping = true
и Джексон ожидал бы, например
<file>
<file>...</file>
<file>...</file>
</file>
вместо того, чтобы просто
<file>...</file>
<file>...</file>
См . Также документ Java of @JacksonXmlElementWrapper
.
В вашем примере XML у вас есть несколько атрибутов XML (например line="126"
, or path="SomePathHere"
), которые, конечно, отличаются от элементов XML (например <line>126</line>
, or <path>SomePathHere</path>
).
Вам нужно сообщить Jackson, что это атрибуты XML, аннотируя свойство Java с @JacksonXmlProperty(isAttribute = true)
помощью . Если вы опустите это, то по умолчанию будет isAttribute = false
и Jackson будет ожидать XML-элемент вместо XML-атрибута.
См . Также документ Java of @JacksonXmlProperty
.