我正在构建一个程序(Visual Studio 2010,.NET 4,基于C#的控制台应用程序),以从公开的政府报告中收集特定信息,该报告仅作为xml下载提供。其结构类似于以下内容:
<Collections>
<Collection>
<Info id="123456" address="Some Place" name="Some Name"/>
<Items>
<Item1/>
<Item2/>
<Item3 I3="Y"/>
<Item3A I3A1="N" I3A2="N" I3A3 = "Y"/>
<Item3B I3B1="N" I3B2="N"/>
<Item4/>
</Items>
</Collection>
<Collection>...</Collection>
<Collection>...</Collection>
</Collections>
完整文件有数百个块,范围从50-100mb。我从来没有使用XML格式甚至远程密切关注这个(它看起来很糟糕,对吧?)并且在尝试查找任何有用的查询示例时遇到了很多麻烦。
我需要为元素Item3到Item3B中具有“Y”的所有节点返回元素的id。它让我有点疯狂,因为如果它们具有匹配的元素名称和匹配属性会很容易,但它们都是独一无二的。您不能在/ Item3 * [Q3 * =“Y”]等XPath查询中包含通配符。
有人对如何解决这个问题有任何想法吗?谢谢!
答案 0 :(得分:0)
我需要从元素中返回所有具有&#34; Y&#34;的节点的id。在元素Item3到Item3B中。
正确的答案取决于确切的&#34;规则&#34;用于选择节点。目前尚不清楚您是否一直在寻找Item3
到Item3B
,或者它们是否只是规则的例子。我还假设节点有一个&#39; Y&#39;在元素&#34;你的意思是他们的属性值等于&#34; Y&#34;。
如果您对正好名称为&#34; Item3&#34;,&#34; Item3A&#34;的三个元素节点感兴趣和&#34; Item3B&#34;,如果&#34; Y&#34;值可以在任何属性上,使用
//*[self::Item3 or self::Item3A or self::Item3B][@* = 'Y']
否则,如果规则只说元素名称必须以&#34; Item3&#34;开头,请使用
//*[starts-with(name(),'Item3')][@* = 'Y']
如果输入XML文档中有命名空间,则使用local-name()
函数而不是name()
会更安全。
您似乎也在尝试匹配以某个字符串开头的属性:
//*[starts-with(name(),'Item3')][@*[starts-with(name(),'Q3')] = 'Y']
如您所见,
您不能在XPath查询中包含通配符,例如/ Item3 * [Q3 * =&#34; Y&#34;]。
不是真的 - 有#34;通配符&#34; (你通常不称它们为通配符),但你需要正确的语法。