我有以下XML实例:
<entities>
<person>
James
</person>
<legalEntity legalName="ACME">
</legalEntity>
<criminalOrganization>
<organizationName>Mafia</organizationName>
</criminalOrganization>
</entities>
并希望使用每个实体的类型和名称生成打印输出。
type 只是元素名称(person
,legalEntity
或criminalOrganization
),
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
)返回。
我的问题是:
为什么在organizationName/text()
的情况下也不会发生这种混淆?
如何在legalEntity
XPath表达式中包含元素名称谓词,以确保每个组件仅评估预期的类型。即union
元素为text()
,person
元素为@legalName
,legalEntity
元素为organizationName/text()
?
答案 0 :(得分:1)
在我看来,你的解决方案有点奇怪,但你可以尝试使用self::
。
试试这个(未经测试):
XPathExpression exprInner
= xpath.compile("self::person/text()|
self::legalEntity/@legalName|
self::criminalOrganization/organizationName/text()");