java 使用 xpath 和 jdom 选择一个节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16315378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Select a node using xpath and jdom
提问by zaki
I have an xform document
我有一个 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>
I would like to select the data element from the xform using xpath and jdom
我想使用 xpath 和 jdom 从 xform 中选择数据元素
XPath xpath = XPath.newInstance("h:html/h:head/h:title/");
seems to work fine and selects the title element but
似乎工作正常并选择了标题元素,但是
XPath xpath = XPath.newInstance("h:html/h:head/model");
does not select the model element. I guess it has something to do with the namespace.
不选择模型元素。我猜这与命名空间有关。
回答by rolfl
A few things. You reallyshould be using JDOM 2.0.x ... (2.0.5 is latest release). The XPath API in the 2.0.x versions is far better than the one in JDOM 1.x: see https://github.com/hunterhacker/jdom/wiki/JDOM2-Feature-XPath-Upgrade
一些东西。您确实应该使用 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 is right about not having the correct namespace for the xforms elements too.... and that is why you XPath is working, because it has the samenamespace as the xhtml elements with the 'h' prefix. Your code is likely to be broken still.
@wds 也没有为 xforms 元素设置正确的命名空间是正确的......这就是您使用 XPath 的原因,因为它与带有 'h' 前缀的 xhtml 元素具有相同的命名空间。您的代码很可能仍然被破坏。
Namespaces in XPaths often confuse people, because everynamespace in an XPath hasto have a prefix. Even if something is the default namespace in the XML (no prefix like your 'model' element), it hasto have one in the XPath. queries with no prefix in the XPath always reference the 'no namespace' namespace.... (XPath specification: http://www.w3.org/TR/xpath/#node-tests)
XPath 中的命名空间经常让人们感到困惑,因为XPath 中的每个命名空间都必须有一个前缀。即使某些东西是 XML 中的默认命名空间(没有像“模型”元素这样的前缀),它也必须在 XPath 中有一个。XPath 中没有前缀的查询总是引用“无命名空间”命名空间......(XPath 规范:http: //www.w3.org/TR/xpath/#node-tests)
A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context
节点测试中的 QName 使用表达式上下文中的命名空间声明扩展为扩展名。这与对开始和结束标签中的元素类型名称进行扩展的方式相同,只是不使用用 xmlns 声明的默认名称空间:如果 QName 没有前缀,则名称空间 URI 为空(这是相同的扩展属性名称的方式)。如果 QName 具有在表达式上下文中没有命名空间声明的前缀,则会出错
Assuming @wds is correct, and the namespace for the model element is supposed to be "http://www.w3.org/2002/xforms" then your namespace delcaration in your document should be xmlns="http://www.w3.org/2002/xforms". But, this namespace is the 'default' namespace, and the URI for the no-prefix namespace in your XPath query is "".
假设@wds 是正确的,并且模型元素的命名空间应该是“ http://www.w3.org/2002/xforms”,那么你在文档中的命名空间声明应该是 xmlns="http://www. w3.org/2002/xforms”。但是,此命名空间是“默认”命名空间,XPath 查询中无前缀命名空间的 URI 是“”。
To access the http://www.w3.org/2002/xformsnamespace in your XPath you have to give it a prefix fo the context of the XPath, let's say xpns (for xpath namespace). In JDOM 1.x you add that namespace with:
要访问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)
Note how that adds the xpns to the query. Also, note that I have 'anchored' the h:/html reference to the '/' root of the document, which will improve the performance of the query evaluation.
请注意如何将 xpns 添加到查询中。另请注意,我已将 h:/html 引用“锚定”到文档的“/”根目录,这将提高查询评估的性能。
IN JDOM 2.x, the XPath API is significanty better (even though in some cases it may seem overkill).
在 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);
See more about the new XPath API in the JDOM 2.x javadoc: XPathFactory.compile(...) javadoc
在 JDOM 2.x javadoc 中查看有关新 XPath API 的更多信息:XPathFactory.compile(...) javadoc