2017-06-03 58 views
0

我想獲取給定XSD類型的所有XML節點。獲取給定XSD類型的所有XML節點

例如(見下面的代碼片斷)

  • 爲XSD類型利斯塔,它應該發現只有1節點 - MyLists/MyListA
  • 爲XSD類型的ItemType,應該找到4個節點 - 2個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> 
+0

一個手動的方法是使用'XSVisitor'來同時解析xml文檔和模式。下面是使用XSVisitor的例子,你可以適應你的用例https://stackoverflow.com/questions/15417330/can-i-re-order-an-existing-xml-to-adhere-to-an-xsd –

回答

2

可以解決與模式敏感的XPath 2.0或更高或模式感知的XQuery 1.0或更高版本通過使用測試像//element(*, YourGlobalTypeName)https://www.w3.org/TR/xpath20/#prod-xpath-ElementTest),所以你的樣品測試//element(*, ListA)返回一個元素,//element(*, ItemType)返回四個元素。在Java世界中,Saxon 9 EE支持支持模式的XPath 2.0/3.0/3.1和XQuery 1.0/3.0/3.1,還有各種各樣的XQuery實現,像exist-db或basex,但我不確定它們是否支持模式感知XQuery的。

+1

因爲Saxon 9 EE需要架構感知xpaths 2.0的許可證,所以我使用了Eclipse PsychoPath - 它僅支持XPath 2.0,而不支持XQuery,但對我的項目來說已經足夠了。 - http://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.wst.xml.xpath2.processor.doc.user%2Fhtml%2Fch02.html – mrq