本文介绍了JAXB:有没有办法只解组XML中的特定路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个XSD,它定义了几种复杂类型的层次结构(每一种都是另一种的孩子)。

I have an XSD which defines a hierarchy of several complex types (each one being a child of the other).

Ex:

<xs:schema version="1.3"
  targetNamespace="https://www.domain.com/schema/reports/export/1.0"
  xmlns:tns="https://www.domain.com/schema/reports/export/1.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">

<xs:element name="detailedreport">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="severity" minOccurs="6" maxOccurs="6" type="tns:SeverityType" />
    </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="SeverityType">
  <xs:sequence>
    <xs:element name="category" minOccurs="0" maxOccurs="unbounded" type="tns:CategoryType"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="CategoryType">
  <xs:sequence>
    <xs:element name="cwe" maxOccurs="unbounded" type="tns:CweType"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="CweType">
  <xs:sequence>
    <xs:element name="staticflaws" type="tns:FlawListType" minOccurs="0"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FlawListType">
  <xs:sequence>
    <xs:element name="flaw" minOccurs="0" maxOccurs="unbounded" type="tns:FlawType" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="FlawType">
  <xs:sequence>
    <xs:element name="mitigations" minOccurs="0" maxOccurs="1" type="tns:MitigationListType" />
    <xs:element name="exploit_desc" type="tns:LongTextType" minOccurs="0" maxOccurs="1"/>
  </xs:sequence>
</xs:complexType>


<xs:complexType name="MitigationListType">
  <xs:sequence>
    <xs:element name="mitigation" minOccurs="0" maxOccurs="unbounded" type="tns:MitigationType"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="MitigationType">
  <xs:attribute name="action" type="xs:string" use="required"/>
  <xs:attribute name="description" type="xs:string" use="required"/>
  <xs:attribute name="user" type="xs:string" use="required"/>
  <xs:attribute name="date" type="xs:string" use="required"/>
</xs:complexType>

</xs:schema>

我想要只导入complexType FlawType 进入清单。我想我可以使用Apache Digester来做这个但是想知道是否有某种方法可以用JAXB做到这一点。解组直接到详细报告对象,然后使用循环来提取FlawType是可行的,但似乎需要做很多额外的工作。

I'm looking to import only complexType FlawType into a list. I figure I can probably use Apache Digester to do this but was wondering if there was some way to do this with JAXB. Unmarshalling direct to a detailedreport object and then using loops to extract the FlawType is feasible, but seems like a lot of extra work.

从本质上讲,我希望能够提出一个类似的解决方案:

In essence, I'm hoping to be able to come up with a solution that would do something like:

   String xml = FileUtils.readFileToString( XML_File );
   unmarshaller = JAXBContext.createUnmarshaller();
   // only unmarhsal nodes of FlawType.class from the xml file.
   List<FlawType> flawTypes = unmarshaller.unmarshal( xml, FlawType.class );

我可以将整个XML文件加载到DOM对象中,然后使用类似XPath的东西来查找所有单个 FlawType 节点,对于每个节点,使用Unmarshaller为每个节点执行此操作,但不知道是否有更简单的方法。我认为我也可以使用某种形式的SAX Parser(我从来没有使用过它们),但我希望能有更直接的东西。

I could probably load the entire XML file into a DOM object, then use something like XPath to locate all the individual FlawType nodes and for each node, use an Unmarshaller to do it for each node, but didn't know if there was an easier way. I presume I might be able to use some form of a SAX Parser as well (I've never used them) but was hoping for something a little more straight forward.

我实际上使用带有spring-oxm软件包的Spring 4框架来处理我的大量JAXB,所以我们希望找到一个易于理解和维护的简单解决方案。使用像Digester这样的东西只会为我的堆栈添加更多技术,我宁愿避免使用它。

I'm actually using the Spring 4 framework with spring-oxm package to handle a lot of the JAXB legwork for me, so would love to find a simple solution that will be easily understood and maintainable. Using something like Digester just adds more technology to my stack which I would much rather avoid.

使用JAXB是否有一种简单的方法可以做到这一点,或者这超出了范围JAXB?

Is there an easy way to do this with JAXB, or this is beyond the scope of JAXB?

推荐答案

我设法找到以下解决方案,但不要认为它是最可能的:

I have managed to find the following as a solution, but don't think it is the prettiest possible:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(IOUtils.toInputStream(xml));
NodeList nodeList = doc.getElementsByTagName("cwe");

JAXBContext jc = JAXBContext.newInstance( CweType.class );
Unmarshaller u = jc.createUnmarshaller();

List<CweType> cwes = new ArrayList<>();
for( int i = 0; i < nodeList.getLength(); i++ )
    cwes.add( u.unmarshal(nodeList.item(i),  CweType.class);

我希望有点整洁。对于初学者,我不喜欢我必须手动搜索的想法名为 cwe 的元素。至少,我希望能够从生成的CweType类或CategoryType类中获取元素名称,但这是我能够做到的唯一方法看到这样做就是反思。这是唯一的方法吗?

I was hoping for something a little neater. For starters, I do not like the idea that I have to manually search for element named cwe. I would, at the very least, like to be able to get the element name from the generated CweType class or the CategoryType class, but the only way I can see doing that is reflection. Is that the only way?

这篇关于JAXB:有没有办法只解组XML中的特定路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 18:05