【问题标题】:Select child nodes, but ignore non-elements with XPath?选择子节点,但使用 XPath 忽略非元素?
【发布时间】:2011-05-18 16:47:12
【问题描述】:

以下面的 XML 文档为例:

<?xml version="1.0"?>
<UrdaObject>
  <Date>
    <Year>2011</Year>
    <Month>5</Month>
    <Day>18</Day>
    <Hours>8</Hours>
    <Minutes>47</Minutes>
    <Seconds>36</Seconds>
  </Date>
  <random_value>24</random_value>
</UrdaObject>

了解child::node() - Selects all child nodes of the current node 我将如何创建一个XPath(从根开始)将选择除文本、cmets 和其他非元素之外的所有子节点。例如,当使用此代码在 WPF 中创建树视图时:

// x is some XmlDocument, xmlTree is my WPF TreeView
XmlDataProvider provider = new XmlDataProvider();
provider.Document = x;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::node()";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);

我将如何创建我的 XPath 语句,以便构建一个树视图,其中的节点一直向下并在原始文本之前停止?例如,它将生成以下视图:

UrdaObject
  Date
    Year
...

而不是...

UrdaObject
  Date
    Year
      2011 (Don't want this!)
...

示例 XML 文件仅用于解释我的情况。表达式应该能够导航任何有效的 XML 文件并提取元素,但不能访问单个文本。


我们如何解决这个问题?我已将所有 child::node() 的引用切换为 child::*。但是,我没有更正我的 XAML 中的一行,即拉动child::node()。更正这条线使应用程序正常运行......让我觉得很傻。

【问题讨论】:

    标签: c# wpf xml xpath


    【解决方案1】:

    child::node() 查找所有子节点。 child::* 查找所有 element 节点。

    【讨论】:

    • 我之前尝试过,但是 child::* 也打开了 C# TreeView 中的各个文本条目(鉴于上面的代码块),但绑定保持访问文本视图,就好像它是一个元素,我似乎可以解释它。
    • ...我从上面收回我的评论。这解决了它,原因如下:我已经正确构建了查询,但是我的 XAML 中的一个模板中的一个愚蠢的错误仍在尝试使用 node() 属性提取所有元素。更正此问题导致树视图正常工作。哇,错过那个我觉得很傻......
    【解决方案2】:

    就像* 一样简单。

    (但是,它会获得直接子元素;如果您想要所有后代元素,则应为 descendant::*

    【讨论】:

      【解决方案3】:

      child::* 将排除文本节点,只保留元素节点

      child::text() 将只包含文本节点

      child::node() 将包括元素和文本节点

      http://www.w3.org/TR/xpath/#location-paths

      【讨论】:

      • 有没有办法可以明确排除文本节点?我认为问题是 TreeView 正在遍历 XML 文件,并且仍在拉出单个文本节点并添加它们,即使使用 child::*
      • 我是个傻瓜,上面的解释。但是我不得不给出 lonesomeday 的答案,因为他有更早的时间戳。
      • 我认为您将 XPath 选择的内容与 TreeView 的显示方式混淆了。
      【解决方案4】:

      不确定这是否是您想要的,但可以这样做吗?

      var doc =XDocument.Parse(@"
      
      <UrdaObject>
        <Date>
          <Year>2011</Year>
          <Month>5</Month>
          <Day>18</Day>
          <Hours>8</Hours>
          <Minutes>47</Minutes>
          <Seconds>36</Seconds>
        </Date>
        <random_value>24</random_value>
      </UrdaObject>
      ");
      
      
      
              var query = from s in doc.Descendants()
                          select s.Name;
      
      
              foreach (var name in query)
              {
                  Console.WriteLine(name);
              }
      

      【讨论】:

      • 1) 我在这个项目中没有使用 XDocument,2) 我在某种程度上受限于使用 XPath 来获得我需要的结果,或者对 TreeView 进行一些先前的 XML 操作。
      猜你喜欢
      • 1970-01-01
      • 2011-07-06
      • 2013-03-12
      • 2011-05-23
      • 1970-01-01
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      相关资源
      最近更新 更多