2012-04-13 124 views
1

我有一个没有一致结构的XML。我需要查看是否有一种简单的方法来搜索所有具有至少一个属性为modified =“yes”的子节点的父节点。有没有简单的方法来做到这一点与XPath?我将要处理的XML非常庞大,我将使用不具备Visual Studio所有功能的4GL语言,但它确实提供了一些COM对象来帮助浏览XML DOM。代码看起来非常相似,我会在Visual Studio做(见示例XML下面)XPath获取具有任何具有特定属性的子节点的所有父节点

示例XML(为了便于可读性大大简化):

<RootNode> 
    <BOOK> 
     <PRICE modified="yes">15</PRICE> 
     <COPIES>10</COPIES> 
    </BOOK> 
    <MAGAZINE> 
     <PRICE>8</PRICE> 
     <COPIES modified="yes">100</COPIES> 
    </MAGAZINE> 
    <NEWSPAPER modified="yes"> 
     <PRICE>2</PRICE> 
     <COPIES>75</COPIES> 
    </NEWSPAPER> 
    <KINDLE_SUB> 
     <PRICE modified="yes">6</PRICE> 
     <COPIES/> 
    </KINDLE_SUB> 
    <EMAIL_SUB> 
     <UNSUBSCRIBE modified="yes">1</UNSUBSCRIBE> 
    </EMAIL_SUB> 
</RootNode> 

在Visual Studio中,你可以做:

XmlDocument xmldoc = new XmlDocument(); 
xmldoc.LoadXml([above xml]); 

XmlNodeList nodelist = xmldoc.SelectNodes(" *XPATH HERE* "); 

应该有希望返回到我:XmlNodeList对象中的BOOK,MAGAZINE,KINDLE_SUB和EMAIL_SUB节点。

不应选择NEWSPAPER节点,因为它没有具有modified =“yes”属性的子节点,即使该NEWSPAPER节点本身具有此属性。

回答

1

尝试:

//*[descendant::*[@modified='yes']] 

或更精确地:

/*/*[descendant::*[@modified='yes']] 

EDIT:什么将与上述的XPath和修改示例XML返回为例。

XML

<RootNode> 
    <BOOK> 
    <PRICE modified="yes">15</PRICE> 
    <COPIES>10</COPIES> 
    </BOOK> 
    <foo> 
    <bar> 
     <baz> 
     <yabba> 
      <dabba> 
      <doo modified="yes"/> 
      </dabba> 
     </yabba> 
     </baz> 
    </bar> 
    </foo> 
    <MAGAZINE> 
    <PRICE>8</PRICE> 
    <COPIES modified="yes">100</COPIES> 
    </MAGAZINE> 
    <NEWSPAPER modified="yes"> 
    <PRICE>2</PRICE> 
    <COPIES>75</COPIES> 
    </NEWSPAPER> 
    <KINDLE_SUB> 
    <PRICE modified="yes">6</PRICE> 
    <COPIES/> 
    </KINDLE_SUB> 
    <EMAIL_SUB> 
    <UNSUBSCRIBE modified="yes">1</UNSUBSCRIBE> 
    </EMAIL_SUB> 
</RootNode> 

//*[descendant::*[@modified='yes']]将返回:

RootNode 
BOOK 
foo 
bar 
baz 
yabba 
dabba 
MAGAZINE 
KINDLE_SUB 
EMAIL_SUB 

/*/*[descendant::*[@modified='yes']]将返回:

+0

这些xpaths不会只选择具有'modified ='yes''但不是父项的元素的第一个祖先吗? – 2012-04-13 20:15:12

+0

@AlehDouhi - 我不确定你的意思,但'@ modified'的深度并不重要。返回的内容根据使用的是哪个xpath而不同。他们都返回OP想要的内容,除了第一个返回'RootNode'。由于OP声明示例XML被大大简化,所以很难说出深度大于示例中预期的结果。我会用一个返回的例子来更新我的答案。 – 2012-04-13 21:12:50

+0

了解。是的,我的意思是如果深度会更大,这些xpaths将不会返回直接父项。 – 2012-04-13 21:22:34

1

大概是这样的:/*//*[*[@modified='yes']]

+0

谢谢DevNull和Aleh。它的作品非常漂亮。 – CraigL 2012-04-14 22:58:16

+2

@CraigL - 请接受一个适合你的答案:) – 2012-04-15 09:40:02

相关问题