C# 在 SelectSingleNode 中使用 XPath:从 XML 中检索单个元素(如果存在)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/883698/
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
Using XPath in SelectSingleNode: Retrieving individual element from XML if it's present
提问by
My XML looks like :
我的 XML 看起来像:
<?xml version=\"1.0\"?>
<itemSet>
<Item>one</Item>
<Item>two</Item>
<Item>three</Item>
.....maybe more Items here.
</itemSet>
Some of the individual Itemmay or may not be present. Say I want to retrieve the element <Item>
two</Item>
if it's present. I've tried the following XPaths (in C#).
某些单独的Item可能存在,也可能不存在。假设我想检索元素<Item>
二(</Item>
如果它存在)。我已经尝试了以下 XPath(在 C# 中)。
XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']")
--- If Item twois present, then it returns me only the first element one. Maybe this query just points to the first element in itemSet, if it has an Item of value two somewhere as a child. Is this interpretation correct?
XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']")
--- 如果 Item two存在,那么它只返回第一个元素one。也许这个查询只是指向 itemSet 中的第一个元素,如果它在某个地方有一个值为 2 的 Item 作为子元素。这个解释正确吗?
So I tried:
所以我试过:
XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']/Item[1]")
--- I read this query as, return me the first<Item>
element within itemSet that has value = 'two'. Am I correct?
XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']/Item[1]")
--- 我将这个查询读为,返回<Item>
itemSet 中具有 value = 'two'的第一个元素。我对么?
This still returns only the first element one. What am I doing wrong?
In both the cases, using the siblings I can traverse the child nodes and get to two, but that's not what I am looking at. Also if two is absent then SelectSingleNode returns null. Thus the very fact that I am getting a successfull return node does indicate the presence of element two, so had I wanted a boolean test to chk presence of two, any of the above XPaths would suffice, but I actually the need the full element <Item>two</Item>
as my return node.
这仍然只返回第一个元素one。我究竟做错了什么?在这两种情况下,使用兄弟节点,我可以遍历子节点并到达两个节点,但这不是我想要的。此外,如果两个不存在,则 SelectSingleNode 返回 null。因此,我得到一个成功的返回节点这一事实确实表明存在元素二,所以如果我想要一个布尔测试来确定是否存在二,上述任何一个 XPath 就足够了,但我实际上需要完整的元素<Item>two</Item>
作为我的返回节点。
[My first question here, and my first time working with web programming, so I just learned the above XPaths and related xml stuff on the fly right now from past questions in SO. So be gentle, and let me know if I am a doofus or flouting any community rules. Thanks.]
[我在这里的第一个问题,也是我第一次使用 Web 编程,所以我现在刚刚从 SO 过去的问题中学习了上述 XPath 和相关的 xml 内容。所以请保持温和,如果我是傻瓜或无视任何社区规则,请告诉我。谢谢。]
采纳答案by Jon Skeet
I think you want:
我想你想要:
myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']")
In other words, you want the Itemwhich has text of two, not the itemSet
containing it.
换句话说,您需要包含两个文本的Item,而不是itemSet
包含它的文本。
You can also use a single dot to indicate the context node, in your case:
您还可以使用一个点来表示上下文节点,在您的情况下:
myXMLdoc.SelectSingleNode("/itemSet/Item[.='two']")
EDIT: The difference between .
and text()
is that .
means "this node" effectively, and text()
means "all the text node children of this node". In both cases the comparison will be against the "string-value" of the LHS. For an element node, the string-value is "the concatenation of the string-values of all text node descendants of the element node in document order" and for a collection of text nodes, the comparison will check whether any text node is equal to the one you're testing against.
编辑:.
和之间的区别text()
是.
有效地表示“此节点”,并text()
表示“此节点的所有文本节点子节点”。在这两种情况下,比较都将针对 LHS 的“字符串值”。对于元素节点,字符串值是“元素节点的所有文本节点后代的字符串值按文档顺序的串联”,对于文本节点的集合,比较将检查是否有任何文本节点等于你正在测试的那个。
So it doesn't matter when the element content only has a single text node, but suppose we had:
所以当元素内容只有一个文本节点时并不重要,但假设我们有:
<root>
<item name="first">x<foo/>y</item>
<item name="second">xy<foo/>ab</item>
</root>
Then an XPath expression of "root/item[.='xy']
" will match the first item, but "root/item[text()='xy']
" will match the second.
然后“ root/item[.='xy']
”的 XPath 表达式将匹配第一项,但“ root/item[text()='xy']
”将匹配第二项。