2013-06-26 187 views
0

我有下面的XML實例:的XPath謂詞

<entities> 
    <person> 
     James 
    </person> 
    <legalEntity legalName="ACME"> 
    </legalEntity> 
    <criminalOrganization> 
     <organizationName>Mafia</organizationName> 
    </criminalOrganization> 
</entities> 

,並希望製作打印出與名稱每個實體的

類型是簡單地將元素名稱(personlegalEntitycriminalOrganization名稱根據種類實體的定義不同。

所以我有以下代碼:

XPathExpression expr = xpath.compile("/entities/(person|legalEntity|criminalOrganization)"); 
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 
for (int i = 0 ; i < nodes.getLength() ; i++) { 
    Node node = nodes.item(i); 
    String nodeName = node.getNodeName(); 
    XPathExpression exprInner = xpath.compile("text()|@legalName|organizationName/text()"); 
    String name = (String) exprInner.evaluate(node); 
    System.out.printf("node type = %s, name = %s\n", nodeName, name); 
} 

的代碼產生輸出:

node type = person, name = 
     James 

node type = legalEntity, name = ACME 
node type = criminalOrganization, name = 

所以基本上,person實體的名稱是取OK(我只是修剪) ,legalEntity的名稱也正確取出,但名稱criminalOrganization不是。

經過調查後,我發現,這是由於這樣的事實中的XPath union結構中的第一個表達式:它返回的評估值text()|@legalName|organizationName/text()還評估(我想一些空字符串值)的criminalOrganization這樣的情況下,整個聯盟表達式(而不是最後一個組件organizationName/text())。

我的問題是:

  1. 爲什麼這不能查詢股價也是在legalEntity的情況下發生的呢?

  2. 如何在union XPath表達式中包含元素名稱謂詞以確保每個組件僅評估預期類型。即text() for person elements,@legalName for legalEntity elements and organizationName/text() for criminalOrganization elements?

回答

1

在我看來你的解決方案有點奇怪,但你可以嘗試使用self::

試試這個(未測試):

XPathExpression exprInner 
     = xpath.compile("self::person/text()| 
         self::legalEntity/@legalName| 
         self::criminalOrganization/organizationName/text()"); 
+0

葉氏,工程。你能詳細說明什麼是奇怪的,以及如何以不同的方式做它,因爲我是XPath的新手,並且不熟悉最佳實踐/常用模式等。 –

+0

另外,爲什麼我沒有看到相同的混淆'legalEntity'元素? –

+1

沒有混淆。你的表達式的'evaluate()'返回一個節點列表,這些節點是按照文檔順序排列的(不是按照你的表達順序排列的,但是法律實體的屬性在任何文本節點之前,'(String)'強制只返回第一個節點的「文本」 –