在 SelectSingleNode 中使用 XPath:从 XML 中检索单个元素(如果存在)

发布于 2024-07-21 05:11:29 字数 1265 浏览 4 评论 0原文

我的 XML 看起来像:

<?xml version=\"1.0\"?>
<itemSet>
       <Item>one</Item>
       <Item>two</Item>
       <Item>three</Item>
       .....maybe more Items here.
</itemSet>

某些单独的 Item 可能存在,也可能不存在。 假设我想检索元素 two(如果存在)。 我已经尝试过以下 XPath(在 C# 中)。

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']") --- 如果存在 Item two,则它仅返回第一个元素一个。 也许这个查询只指向 itemSet 中的第一个元素,如果它在某个地方有一个值为 2 的 Item 作为子元素。 这个解释正确吗?

所以我尝试了:

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']/Item[1]") --- 我将此查询读为,返回第一个 itemSet 中 value = 'two' 的元素。 我对么?

这仍然只返回第一个元素 one。 我究竟做错了什么? 在这两种情况下,使用兄弟节点我可以遍历子节点并到达两个,但这不是我要查看的。 另外,如果两个不存在,则 SelectSingleNode 返回 null。 因此,我获得成功返回节点的事实确实表明元素二的存在,因此如果我想要一个布尔测试来检查 two 的存在,上述任何 XPath 都足够了,但我实际上需要完整的元素 two作为我的返回节点。

[我的第一个问题是在这里,也是我第一次使用 Web 编程,所以我刚刚从 SO 中过去的问题中即时了解了上述 XPath 和相关的 xml 内容。 因此,请保持温柔,如果我是个傻瓜或藐视任何社区规则,请告诉我。 谢谢。]

My XML looks like :

<?xml version=\"1.0\"?>
<itemSet>
       <Item>one</Item>
       <Item>two</Item>
       <Item>three</Item>
       .....maybe more Items here.
</itemSet>

Some of the individual Item may 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#).

  • XMLNode node = myXMLdoc.SelectSingleNode("/itemSet[Item='two']") --- If Item two is 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?

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?

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.

[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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

左耳近心 2024-07-28 05:11:29

我认为您想要:

myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']")

换句话说,您想要具有两个文本的 Item,而不是包含它的 itemSet

您还可以使用单个点来指示上下文节点,在您的情况下:

myXMLdoc.SelectSingleNode("/itemSet/Item[.='two']")

编辑: .text() 之间的区别在于 . > 有效地表示“此节点”,text() 表示“此节点的所有文本节点子节点”。 在这两种情况下,比较都将针对 LHS 的“字符串值”。 对于元素节点,字符串值是“按文档顺序排列元素节点的所有文本节点后代的字符串值的串联”,对于文本节点的集合,比较将检查是否有任何文本节点等于你正在测试的那个。

因此,当元素内容只有一个文本节点时并不重要,但假设我们有:

<root>
  <item name="first">x<foo/>y</item>
  <item name="second">xy<foo/>ab</item>
</root>

那么“root/item[.='xy']”的 XPath 表达式将匹配第一个item,但“root/item[text()='xy']”将匹配第二个。

I think you want:

myXMLdoc.SelectSingleNode("/itemSet/Item[text()='two']")

In other words, you want the Item which has text of two, not the itemSet containing it.

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.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文