XPath谓词在条件表达式中

时间:2013-06-26 18:05:37

标签: java xpath

我有以下XML实例:

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

并希望使用每个实体的类型名称生成打印输出。

type 只是元素名称(personlegalEntitycriminalOrganization), name 的定义根据实体的类型而有所不同。

所以我有以下代码:

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实体的名称被提取好了(我只需修剪它),legalEntity的名称也被正确提取,但criminalOrganization的名称是不。

经过调查,我发现这是因为XPath union结构中的第一个表达式:text()|@legalName|organizationName/text()在{{{}}的情况下也评估(我想某些空字符串值) 1}}所以它作为整个联合表达式的评估值(而不是最后一个组件criminalOrganization)返回。

我的问题是:

  1. 为什么在organizationName/text()的情况下也不会发生这种混淆?

  2. 如何在legalEntity XPath表达式中包含元素名称谓词,以确保每个组件仅评估预期的类型。即union元素为text()person元素为@legalNamelegalEntity元素为organizationName/text()

1 个答案:

答案 0 :(得分:1)

在我看来,你的解决方案有点奇怪,但你可以尝试使用self::

试试这个(未经测试):

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