【问题标题】:Select a node using xpath and jdom使用 xpath 和 jdom 选择节点
【发布时间】:2013-04-25 06:53:56
【问题描述】:

我有一个 xform 文档

<?xml version="1.0" encoding="UTF-8"?><h:html xmlns:h="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa">
<h:head>
    <h:title>Summary</h:title>
    <model>
        <instance>
            <data vaultType="nsp_inspection.4.1">
                <metadata vaultType="metadata.1.1">
                    <form_start_time type="dateTime" />
                    <form_end_time type="dateTime" />
                    <device_id type="string" />
                    <username type="string" />
                </metadata>
                <date type="date" />
                <monitor type="string" />
            </data>
        </instance>
    </model>
</h:head>

我想使用 xpath 和 jdom 从 xform 中选择数据元素

XPath xpath = XPath.newInstance("h:html/h:head/h:title/");

似乎工作正常并选择了标题元素,但是

XPath xpath = XPath.newInstance("h:html/h:head/model");

不选择模型元素。 我想这与命名空间有关。

【问题讨论】:

  • 看来是默认命名空间问题。这个答案有帮助吗:stackoverflow.com/a/6390494/10098?顺便说一句,你的默认命名空间可能是错误的,如果我没记错的话应该是w3.org/2002/xforms
  • 这似乎可以打勾。 XPath xpath = XPath.newInstance("//h:model"); tanx @wds 链接。

标签: java xml xpath jdom javarosa


【解决方案1】:

一些事情。你真的应该使用 JDOM 2.0.x ...(2.0.5 是最新版本)。 2.0.x 版本中的 XPath API 比 JDOM 1.x 中的要好得多:参见https://github.com/hunterhacker/jdom/wiki/JDOM2-Feature-XPath-Upgrade

@wds 也没有为 xforms 元素提供正确的命名空间是正确的......这就是 XPath 工作的原因,因为它具有与 xhtml 元素相同的 same 命名空间'h' 前缀。您的代码很可能仍然被破坏。

XPath 中的命名空间常常让人们感到困惑,因为 XPath 中的每个 命名空间必须 有一个前缀。即使某些东西是 XML 中的默认命名空间(没有像您的“模型”元素这样的前缀),它必须在 XPath 中有一个。 XPath 中没有前缀的查询总是引用“无命名空间”命名空间....(XPath 规范:http://www.w3.org/TR/xpath/#node-tests

节点测试中的 QName 使用命名空间扩展为扩展名称 来自表达式上下文的声明。这与扩展的方式相同 用于开始和结束标记中的元素类型名称,默认命名空间除外 不使用 xmlns 声明:如果 QName 没有前缀,则 命名空间 URI 为空(这与扩展属性名称的方式相同)。它是 如果 QName 有一个在其中没有命名空间声明的前缀,则会出现错误 表达式上下文

假设@wds 是正确的,并且模型元素的命名空间应该是“http://www.w3.org/2002/xforms”,那么文档中的命名空间声明应该是 xmlns="http://www.w3.org/2002/xforms ”。但是,此命名空间是“默认”命名空间,XPath 查询中无前缀命名空间的 URI 是“”。

要访问 XPath 中的 http://www.w3.org/2002/xforms 命名空间,您必须为其提供 XPath 上下文的前缀,例如 xpns(用于 xpath 命名空间)。在 JDOM 1.x 中,您添加该命名空间:

XPath xpath = XPath.newInstance("/h:html/h:head/xpns:model");
xpath.addNamespace(Namespace.getNamespace("xpns", "http://www.w3.org/2002/xforms");
Element model = (Element)xpath.selectSingleNode(mydoc)

请注意如何将 xpns 添加到查询中。另外,请注意,我已将 h:/html 引用“锚定”到文档的“/”根,这将提高查询评估的性能。

在 JDOM 2.x 中,XPath API 明显更好(尽管在某些情况下它可能看起来有点矫枉过正)。

XPathFactory xpf = XPathFactory.instance();
XPathExpression<Element> xpath = xpf.compile("/h:html/h:head/xpns:model",
              Filters.element(), null,
              Namespace.getNamesace("xpns", "http://www.w3.org/2002/xforms"));
Element model = xpath.evaluateFirst(mydoc);

在 JDOM 2.x javadoc 中查看有关新 XPath API 的更多信息:XPathFactory.compile(...) javadoc

【讨论】:

    猜你喜欢
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多