【问题标题】:Deleting node from string with xml structure从带有xml结构的字符串中删除节点
【发布时间】:2013-12-18 13:30:17
【问题描述】:

我有一个字符串参数,其中包含 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 objetc,但 SelectSingleNode 返回 null。

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

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

编辑:这是我测试的 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>

【问题讨论】:

  • 您是否有特定原因无法创建XmlDocument 实例、调用LoadXml() 并进行处理?我问是因为你写了“不是 XML 对象”。
  • funcThatReturnsXML (parameters) 中,它创建了一个XML Object,但将其作为string xmlObject.InnerXml 返回。我不能改变这个基本函数,所以我只想修复我正在处理的字符串
  • 我建议你(重新)从字符串构建一个 XmlDocument。
  • 试过了...xmlDoc.SelectSingleNode("tagB"); 返回 null
  • xpath 错误...尝试xmlDoc.SelectSingleNode("/tagA/tagB")xmlDoc.SelectSingleNode("//tagB")

标签: c# .net xml


【解决方案1】:

试试这个:

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

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

更新 1:

抱歉,我错过了再添加一行:

S = doc.ToString();

我上面的第一个代码从 doc 中删除了“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 ,这将在忽略其命名空间的同时搜索节点名称。以下示例显示了如何删除所有“信息”节点:

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

【讨论】:

  • @Dima 看到我的更新。如果您检查了是否从 S 中删除了 ,那么是的,它不是,但它会在末尾添加 S = doc.ToString();
  • @Dima 我使用包含属性的 xml 进行了测试,并且程序仍在运行。如果它仍然不适合您,请告诉我您拥有的 xml
  • 它仍然无法正常工作,我将 XML 添加到我的问题中
  • @Dima 更新了我的答案。试试看,它对我有用。
【解决方案2】:

如果您可以确定要从返回的 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 方法返回的名称,它们将全部被删除。如果你想删除一个特定的实例,那么你将需要更复杂的东西。

【讨论】:

    【解决方案3】:

    以您的编辑为基础:

    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);
    }
    

    【讨论】:

    • 谢谢解答,问题是&lt;tagB&gt;每次都在不同的地方,不认识所有的家长就不能找到吗?
    • '//tagB'是一个贪婪的xpath的意思;将任何元素带到任何地方'。因此,即使 tagB 嵌套在不同级别的多个元素深处,它也可以工作。
    猜你喜欢
    • 2021-08-06
    • 1970-01-01
    • 2020-08-22
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多