【问题标题】:XPath predicates in conditional expressions条件表达式中的 XPath 谓词
【发布时间】:2013-06-27 02:48:21
【问题描述】:

我有以下 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()criminalOrganization 的情况下也会计算(我想是一些空字符串值)所以它是作为整个联合表达式的计算值返回(而不是最后一个组件organizationName/text())。

我的问题是:

  1. 为什么在legalEntity的情况下也不会发生这种混淆?

  2. 如何在union XPath 表达式中包含元素名称谓词,以确保每个组件仅针对预期类型进行评估。 IE。 text() 用于person 元素,@legalName 用于legalEntity 元素和organizationName/text() 用于criminalOrganization 元素?

【问题讨论】:

    标签: java xpath


    【解决方案1】:

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

    试试这个(未测试):

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

    【讨论】:

    • 是的,这行得通。您能否详细说明什么是奇怪的以及您将如何以不同的方式进行操作,因为我是 XPath 的新手,不熟悉最佳实践/常用模式等。
    • 另外,为什么我在legalEntity 元素的情况下没有看到相同的混淆?
    • 没有混淆。带有您的表达式的evaluate() 返回一个节点列表,节点按文档顺序排列(不是按您的表达式顺序。但legalEntity is before any text-node. The (String) ` 的属性强制仅返回第一个节点的“文本” .
    • 我宁愿在第一个评估的节点名称上使用 switch case,而不是根据已知节点选择内容(即使这会是更多代码)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多