获取给定XSD类型的所有XML节点

时间:2017-06-03 11:50:10

标签: java xml xpath xsd

我想获得给定XSD类型的所有XML节点。

例如(参见下面的代码片段)

  • 对于XSD类型 ListA ,它应该只找到1个节点 - MyLists / MyListA
  • 对于XSD类型 ItemType ,它应该找到4个节点--2x MyLists / MyListA / ItemA 和2x MyLists / MyListB / ItemB ,但不是MyLists / MyListC /中的节点,因为它们是 CustomItemType 的类型(尽管它们具有相同的名称 - 类型不同)。

是否有可以提供此功能的java库?

或任何想法如何手动解决? XSD可能非常复杂,导入其他模式等。 我正在考虑通过遍历XSD架构(没有递归)生成具有给定类型的节点的所有可能的xPath,然后将它们应用于XML文件并检查是否找到了一些节点。

XSD示例

<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
           xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>


  <xs:complexType name="ListA">
    <xs:sequence>
      <xs:element name="ItemA" type="ItemType" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ListB">
    <xs:sequence>
      <xs:element name="ItemB" type="ItemType" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType> 

  <xs:complexType name="AnotherList">
    <xs:sequence>
      <xs:element name="ItemA" type="CustomItemType" maxOccurs="unbounded"/>
      <xs:element name="ItemB" type="CustomItemType" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType> 

  <xs:complexType name="ItemType">
    <xs:sequence>
      <xs:element name="ID"  type="xs:string" />
      <xs:element name="Value" type="xs:string" />      
    </xs:sequence> 
  </xs:complexType> 

  <xs:complexType name="CustomItemType">
    <xs:sequence>
      <xs:element name="ID"  type="xs:string" />
      <xs:element name="Value" type="xs:string" />      
    </xs:sequence> 
  </xs:complexType>   

  <xs:element name="MyLists">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="MyListA" type="ListA" />  
        <xs:element name="MyListB" type="ListB" />
        <xs:element name="MyListC" type="AnotherList" />
      </xs:sequence>
    </xs:complexType>  
  </xs:element>  
</xs:schema>

XML示例

<MyLists>
  <MyListA>
    <ItemA>
      <ID>1</ID>
      <Value>A1</Value>
    </ItemA>
    <ItemA>
      <ID>2</ID>
      <Value>A2</Value>
    </ItemA>
  </MyListA>
  <MyListB>
    <ItemB>
      <ID>1</ID>
      <Value>B1</Value>
    </ItemB>
    <ItemB>
      <ID>2</ID>
      <Value>B2</Value>
    </ItemB>
  </MyListB>
  <MyListC>
    <ItemA>
      <ID>1</ID>
      <Value>A1</Value>
    </ItemA>
    <ItemB>
      <ID>2</ID>
      <Value>B1</Value>
    </ItemB>
  </MyListC>
</MyLists>

1 个答案:

答案 0 :(得分:2)

您可以使用类似//element(*, YourGlobalTypeName)https://www.w3.org/TR/xpath20/#prod-xpath-ElementTest)之类的测试来解决使用架构感知的XPath 2.0或更高版本或架构感知的XQuery 1.0或更高版本,因此您的示例将使用{{1返回一个元素,//element(*, ListA)返回四个元素。在Java世界中,Saxon 9 EE支持模式感知XPath 2.0 / 3.0 / 3.1和XQuery 1.0 / 3.0 / 3.1,还有各种XQuery实现,如exists-db或basex,但我不确定它们是否支持模式感知的XQuery。