c# xmldocument 获取特定节点之后的所有兄弟节点

Posted

技术标签:

【中文标题】c# xmldocument 获取特定节点之后的所有兄弟节点【英文标题】:c# xmldocument get all siblings nodes after a specific one 【发布时间】:2021-05-18 19:47:58 【问题描述】:

假设我有以下 xml:

<Report>
    <Tablix></Tablix>
    <Textbox Name="TextboxSearchInjection"></Textbox>
    <Textbox></Textbox>
    <Tablix></Tablix>
    <Textbox></Textbox>
    <Textbox Name="TextboxSearchInjectionEnd">
       <Height>1</Height>
    </Textbox>
    <Tablix>
       <Height>1</Height>
    </Tablix>
   <Textbox>
       <Height>2</Height>
    </Textbox>
   <Textbox></Textbox>
   <Tablix>
      <Height>1</Height>
   </Tablix>
   <Textbox>
       <Height>3</Height>
    </Textbox>
</Report>

如何在 c# 中使用 XmlDocument 获取 &lt;Textbox Name="TextboxSearchInjectionEnd"&gt; 之后的所有兄弟节点并更新 Height 中的值? 所以最后我会收到像 Textbox 和 Tablix 这样的节点列表,但从节点 &lt;Textbox Name="TextboxSearchInjectionEnd"&gt; 开始。我以前不想要。

【问题讨论】:

为什么要使用旧的XmlDocument,而不是更现代、更方便的XDocument 对不起,我忘记删除一些标签,现在应该是有效的 xml。为什么要使用 XmlDocument - 好问题 - 因为我所有的解决方案都不幸地基于旧技术并且为了保持一致性,我想解决这个问题。 是要修改&lt;Textbox Name="TextboxSearchInjectionEnd"&gt;的兄弟节点的高度还是要更新&lt;Textbox Name="TextboxSearchInjectionEnd"&gt;本身的高度? Tablix 的 +height 也是如此 【参考方案1】:

您可以使用NextSibling 检索所有后续的兄弟节点。例如,

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var node = doc.SelectSingleNode(@"//*[@Name='TextboxSearchInjectionEnd']");
var result = GetAllSucceedingSiblingNodes(node);

GetAllSucceedingSiblingNodes 定义为

IEnumerable<XmlNode> GetAllSucceedingSiblingNodes (XmlNode node)

    var currentNode = node.NextSibling; // Use currentNode = node if you want to include searched node
    while(currentNode!=null)
    
        yield return currentNode;
        currentNode = currentNode.NextSibling;
    

【讨论】:

感谢 Anu 的解决方案!它几乎工作得很好。有一个小问题。我更新了我之前的 xml 示例,并添加了一个节点属性 Name="TextboxSearchInjection"。在这种情况下,它会占用我所有的节点。如何解决?是的,我确实需要使用 var currentNode = node; 关于您提到的故障,请您使用以下dotnetfiddle.net/w30UMS进行验证【参考方案2】:

好的,Anu 我有基于您的解决方案:

        private static IEnumerable<XmlNode> GetAllSucceedingSiblingNodes(XmlNode node, XmlNamespaceManager nsmgr)
        
            var currentNode = node;//.NextSibling; // Use currentNode = node if you want to include searched node
            while (currentNode != null &&
                currentNode.Attributes["Name"].Value != "TextboxSearchInjection")
            
                yield return currentNode;
                currentNode = currentNode.NextSibling;
            
        

再次感谢您!

【讨论】:

我认为你不需要这个 'currentNode.Attributes["Name"].Value != "TextboxSearchInjection")'。请检查以下dotnetfiddle.net/w30UMS 不幸的是我确实需要它,否则它需要 TextboxSearchInjection 以及 TextboxSearchInjectionEnd 兄弟姐妹。

以上是关于c# xmldocument 获取特定节点之后的所有兄弟节点的主要内容,如果未能解决你的问题,请参考以下文章

c# .net 怎么将一个xml字符串 转换成一个xmlnode ,(不是xmldocument)

计算特定XML节点c#的子节点数[重复]

C# 使用 XmlReader 但不使用 XmlDocument 获取额外的空白值

XmlDocument 类正在删除格式、c#、.NET

在C#中 xmldocument xpath 模糊查询 忽略大小写

无论特定 Id 如何,如何使用 XPath 选择类别 XML 节点?