使用xml结构从字符串中删除节点

时间:2013-12-18 13:30:17

标签: c# .net xml

我有一个带有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返回null。

 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>

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

以编辑为基础:

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

答案 2 :(得分:0)

试试这个:

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,它将在忽略其名称空间的同时搜索节点名称。下面的示例显示了如何删除所有“info”节点:

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