从具有 xml 结构的字符串中删除节点

本文关键字:字符串 删除 节点 结构 xml | 更新日期: 2024-10-26 06:54:40

我有一个包含xml内容的字符串参数。基本上,字符串内部有一个XML

string S = funcThatReturnsXML (parameters);

S有下一条文字:

<?xml version="1.0" encoding="utf-8" ?> 
<tagA>
<tagB> 
<tagBB>
..
.
.
</tagBB>
.
.
</tagB>
<tagC> 
..
..
.
</tagC>
</tagA>

funcThatReturnsXML (parameters)创建一个XmlDocument对象,但将其作为string返回,我无法更改此函数,很多东西都可以使用它。

已尝试创建 XmlDocument 对象,但SelectSingleNode返回空值。

 XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(S);
                    XmlNode root = xmlDoc.SelectSingleNode("tagB");

如何从字符串S(不是XML对象)特定节点中删除,例如<tagB>

编辑:这是我测试的XML:

 <?xml version="1.0" ?> 
- <Request xmlns:xsi="http://www.mysite.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <info xmlns="http://www.mysite.com">
  <RequestTR>54</RequestTR> 
  <time>2013-12-22</time> 
  </info>
- <Parameters xmlns="http://www.mysite.com">
  <id>3</id> 
  <name>2</name> 
  </Parameters>
  <title>Request</title> 
  </Request>

从具有 xml 结构的字符串中删除节点

试试这个:

string S = funcThatReturnsXML(parameters);
var doc = XDocument.Parse(S);
var nodeToRemove = doc.Descendants("tagB");
nodeToRemove.Remove();

这将从包含 xml 的字符串 S 中删除所有名为"tagB"的节点。

更新 1:

抱歉,我错过了再包含一行:

S = doc.ToString();

我上面的第一个代码从文档中删除了"tagB",但没有将其保存回 S 变量。

更新 2:

我使用以下包含属性的 xml 进行了测试:

<tagA attribute="value">
    <tagB> 
        <tagBB>
        </tagBB>
    </tagB>
    <tagC></tagC>
</tagA>

Console.WriteLine(S)的输出:

<tagA attribute="value">
    <tagC></tagC>
</tagA>

更新 3:

鉴于您更新的 xml 格式,我知道为什么我以前的代码对您不起作用。这是因为您的 xml 声明了命名空间 (xmlns)。解决方案是在搜索要删除的节点时使用 LocalName,这将搜索节点名称,同时忽略其命名空间。以下示例演示如何删除所有"info"节点:

var doc = XDocument.Parse(S);
var nodeToRemove = doc.Descendants().Where(o => o.Name.LocalName == "info");
nodeToRemove.Remove();
S = doc.ToString();

如果可以确定要从返回的 XML 中删除的特定外部元素,则可以使用 LINQ to XML:

var returnedXml = funcThatReturnsXML(parameters);
var xmlElementToRemove = funcThatReturnsOuterElement(returnedXml);
var xelement = XElement.Load("XmlDoc.txt");
xelement.Elements().Where(e => e.Name == xmlElementToRemove).Remove();

例如:

using System.Linq;
using System.Xml.Linq;
class Program
{
    static void Main(string[] args)
    {
        // pretend this is the funThatReturnsXML return value
        var returnedXml = "<tagB><tagBB></tagBB></tagB>";
        // get the outer XML element name
        var xmlElementToRemove = GetOuterXmlElement(returnedXml);
        // load XML from where ever
        var xelement = XElement.Load("XmlDoc.txt");
        // remove the outer element and all subsequent elements
        xelement.Elements().Where(e => e.Name == xmlElementToRemove).Remove();
    }
    static string GetOuterXmlElement(string xml)
    {
        var index = xml.IndexOf('>');
        return xml.Substring(1, index - 1);
    }
}

请注意,以上是一种"贪婪"的删除方法,如果有多个元素通过 GetOuterXmlElemet 方法返回名称,它们都将被删除。 如果您希望删除特定实例,则需要更复杂的实例。

基于您的编辑:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(S);
var nodeA = xmlDoc.SelectSingleNode("/tagA");
var nodeB = nodeA.SelectSingleNode("tagB");
nodeA.RemoveChild(nodeB);

要删除(可能)未知位置的多个tagB节点,您可以尝试:

var bees = xmlDoc.SelectNodes("//tagB");
foreach (XmlNode bee in bees) {
    var parent = bee.ParentNode;
    parent.RemoveChild(bee);
}