XPath - 从父元素获取id属性

时间:2011-08-24 09:01:54

标签: java

我有以下xml文件:

<diagnostic version="1.0">
  <!-- diagnostic panel 1 -->
  <panel xml:id="0">
    <!-- list controls -->
    <control xml:id="0_0">
      <settings description="text 1"/>
    </control>
    <control xml:id="0_1">
      <settings description="text 2"/>
    </control>
  </panel>
  <panel xml:id="1">
    <!-- list controls -->
    <control xml:id="1_0">
      <settings description="text 3"/>
    </control>
    <control xml:id="1_1">
      <settings description="text 4"/>
    </control>
  </panel>
</diagnostic>

和定义XPath:

//*[not(@description='-')]/@description

和Java代码:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
domFactory.setNamespaceAware(true);  
DocumentBuilder builder = domFactory.newDocumentBuilder(); 
Document doc = builder.parse("diagnostic.xml"); 
XPath xpath = XPathFactory.newInstance().newXPath(); 
// XPath Query for showing all nodes value 
XPathExpression expr = xpath.compile("//*[not(@description='-')]/@description"); 

Object result = expr.evaluate(doc, XPathConstants.NODESET); 
NodeList nodes = (NodeList) result; 
for (int i = 0; i < nodes.getLength(); i++) { 
  System.out.println(i + ": " + nodes.item(i).getParentNode()  + nodes.item(i).getNodeValue());  
} 

XPath的这个定义将返回所有属性值 description ,其中此属性的值不是“ - ”。

输出:

text 1
text 2
text 3
text 4

但是我需要找到这个属性描述也属性 xml:id 元素控制

输出:

0_0 text 1
0_1 text 2
1_0 text 3
1_1 text 4

如何在我的描述中执行此操作还会返回控件 xml:id 元素?我需要知道给定元素的描述是控制

2 个答案:

答案 0 :(得分:0)

如果我错了,有人会纠正我,但我不认为这可以通过单个XPath表达式完成。 concat函数返回单个文本结果,而不是列表。我建议您运行多个XPath表达式并从中构造结果,或者运行单个XPath表达式以获取所需的settings元素,然后从中获取description属性并将其与{{xml:id连接起来。 1}}来自父元素的属性,如果它是control个元素。 节点保留对父母的引用。使用方法getParentNode()来获取它。

这是另一种选择:运行此XPath表达式......

//control[settings[@description!='-']]/@xml:id | //control/settings[@description!='-']/@description

...然后在返回的节点列表中连接交替结果的文本。换句话说,项目0 +项目1中的文本,项目2 +项目3中的文本等

上面的XPath表达式将返回此节点列表:

0_0
text 1
0_1
text 2
1_0
text 3
1_1
text 4

然后,您可以解析该列表并构建结果。

小心点。这仅适用于每个settings元素最多1 control个元素的情况。此外,您可能会发现在评估时,XPath引擎会为该xml:前缀抛出错误。可能会说这是未知的。您可能必须先将该前缀绑定到正确的命名空间。由于xml前缀是保留的并且默认绑定到特定命名空间,因此可能不需要这样做。我不确定,因为我之前没有使用它。

我在XMLSpy中测试了表达式。 Java中使用的XPath引擎(或您设​​置使用的XPath引擎)以其他顺序返回节点并非完全不可能。它可以分别评估“或”(管道符号)的两个部分,然后将结果转储到单个节点列表中。我不知道XPath规范对结果排序的要求。

答案 1 :(得分:0)

我可能同样错,但您在结果中遍历的节点是XML节点本身。您的代码示例几乎就在那里:
- nodes.item(i)指向属性“description” - nodes.item(i).getParentNode()指向标记“settings” - nodes.item(i).getParentNode()。getParentNode()将指向标签“control”(类Element)。然后,您可以在该节点上使用getAttribute()或getAttributeNS()来查找获取所需的属性。