C# 在不影响子节点的情况下读取和修改xmlNodes

C# 在不影响子节点的情况下读取和修改xmlNodes,c#,xml,C#,Xml,我想处理一大块XML。我用C#写这篇文章,但将使用psuedocode来解释我想做什么。如果你需要更多的信息,请告诉我。在C#中,我将XML加载到XMLDocument中,如下所示: XmlDocument templateDoc = new XmlDocument(); templateDoc.LoadXml(selectionTemplate); XmlNodeList orderNodes = templateDoc.GetElementsB

我想处理一大块XML。我用C#写这篇文章,但将使用psuedocode来解释我想做什么。如果你需要更多的信息,请告诉我。在C#中,我将XML加载到XMLDocument中,如下所示:

XmlDocument templateDoc = new XmlDocument();
            templateDoc.LoadXml(selectionTemplate);
            XmlNodeList orderNodes = templateDoc.GetElementsByTagName("order");
<sort>
  <order name="panelCode">
  <panelCode/>
  </order>
  <order name="panelName">
  <panelName/>
  </order>
  <order name="panelPart">
  <panelPart/>
  </order>
  <order name="numberLayers">ascending
  <numberLayers/>
    <panelCode>ascending|ascending
    </panelCode>
  </order>
</sort>
XML:

作为如何工作的一个例子

如果我的字符串是panelCode,我将遍历所有订单节点。第一个是匹配项,因此我将该order节点的值设置为“升序”。然后,我将遍历其余的order节点,查找其中任何一个具有升序/降序值的节点。这对于numberLayers order节点是正确的,我想将其值设置为“”,但保持子节点的值,例如升序|升序。因此,解析后的文档如下所示

新XML:

<sort>
  <order name="panelCode">ascending
  <panelCode/>
  </order>
  <order name="panelName">
  <panelName/>
  </order>
  <order name="panelPart">
  <panelPart/>
  </order>
  <order name="numberLayers">
  <numberLayers/>
    <panelCode>ascending|ascending
    </panelCode>
  </order>
</sort>

提升
上升的|上升的
如果我拥有的字符串是numberLayers,那么提供的XML将如下所示:

XmlDocument templateDoc = new XmlDocument();
            templateDoc.LoadXml(selectionTemplate);
            XmlNodeList orderNodes = templateDoc.GetElementsByTagName("order");
<sort>
  <order name="panelCode">
  <panelCode/>
  </order>
  <order name="panelName">
  <panelName/>
  </order>
  <order name="panelPart">
  <panelPart/>
  </order>
  <order name="numberLayers">ascending
  <numberLayers/>
    <panelCode>ascending|ascending
    </panelCode>
  </order>
</sort>

提升
上升的|上升的

好的,我想我有你的答案:

XML结构有点棘手的是,在同一级别上有文本节点和其他XML节点(如
)。处理这个问题的技巧是XPath表达式中的
text()
选择器。下面是我要写的:

string targetName = "numberLayers";

// grab the first matching order node
XmlNode matchOrderNode= xmldoc.SelectSingleNode(
                  "//order[@name='" + targetName + "']"); 

// try to grab the first #text leaf node, if not existing, append new 
XmlNode matchTextChildNode = matchOrderNode.SelectSingleNode("./text()"); 
if (matchTextChildNode == null)
{
       matchTextChildNode = matchOrderNode.AppendChild(xmldoc.CreateTextNode(string.Empty));
}

// determine whether 'ascending' is set already --> toggle
string textToSetAfterwards = "ascending";
if (matchTextChildNode.Value == "ascending")
{
    textToSetAfterwards = "descending";
}

// clear all ascending/descending text nodes
foreach (XmlNode orderNode in xmldoc.SelectNodes(
       "//order[text()='ascending' or text()='descending']/text()"))
{
    orderNode.Value = string.Empty;
}

// re-set only the matched node's value
matchTextChildNode.Value = textToSetAfterwards;

您可以使用XPath直接选择#文本叶节点。这些#text节点的
属性中实际上包含纯文本内容(例如“升序”或“降序”),可以读取和设置这些内容

我不完全理解你需要实现什么。你能再提供一些上下文信息吗?我已经编辑了原始答案。请让我知道htis是否有帮助。你到底迷路了什么?好吧,我现在明白了。隐马尔可夫模型。。我现在看不出一种优雅的方式。无论如何,我会很快尝试将您的伪代码转换为真实代码我遇到的问题是识别和更改订单节点的值,而不干扰其任何子节点的值。看起来不错。我曾在谷歌上搜索过/text()xpath,但不知道如何使用它。我将尝试实现这一点,并让您知道它是如何进行的。非常感谢:数据此代码存在问题。如果你正在翻转上升和下降,它可以很好地工作。但是,如果要将新节点设置为升序行XmlNode match=templateDoc.SelectSingleNode(“//order[@name=”+“+columnName+”]/text()[1]”;不返回元素,因为节点中没有文本。啊,你更快了。无论如何,我想我们做了同样的事情,或多或少是的,看起来很相似。非常感谢你的帮助,朋友:如果可以的话,D会给你5分。再次感谢。你给我的解释很好,因为我当时能够自己给出答案,而不是仅仅给出答案