2013-06-26 150 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)'强制只返回第一个节点的“文本” –