C# 从具有xml结构的字符串中删除节点
我有一个字符串参数,其中包含xml内容。基本上,字符串内部有一个C# 从具有xml结构的字符串中删除节点,c#,.net,xml,C#,.net,Xml,我有一个字符串参数,其中包含xml内容。基本上,字符串内部有一个XML string S = funcThatReturnsXML (parameters); S有下一个文本: <?xml version="1.0" encoding="utf-8" ?> <tagA> <tagB> <tagBB> .. . . </tagBB> . . </tagB> <tagC> .. .. . </t
XML
string S = funcThatReturnsXML (parameters);
S
有下一个文本:
<?xml version="1.0" encoding="utf-8" ?>
<tagA>
<tagB>
<tagBB>
..
.
.
</tagBB>
.
.
</tagB>
<tagC>
..
..
.
</tagC>
</tagA>
如何从字符串S
(非XML对象)的特定节点删除,例如
编辑:这是我测试的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>
-
-
54
2013-12-22
-
3.
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);
}
}
使用System.Linq;
使用System.Xml.Linq;
班级计划
{
静态void Main(字符串[]参数)
{
//假设这是funThatReturnsXML返回值
var returnedXml=“”;
//获取外部XML元素名称
var xmlementtoremove=getouterxmlement(returnedXml);
//从何处加载XML
var-xelement=xelement.Load(“XmlDoc.txt”);
//拆下外部元件和所有后续元件
element.Elements().Where(e=>e.Name==xmlElementToRemove.Remove();
}
静态字符串GetOuterXmlElement(字符串xml)
{
var index=xml.IndexOf('>');
返回xml.Substring(1,索引-1);
}
}
请注意,以上是一种“贪婪”删除方法,如果有多个元素的名称通过getouterxmlemet
方法返回,它们将全部删除。如果要删除某个特定实例,则需要更复杂的操作。尝试以下操作:
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>
更新3:
鉴于您更新的xml格式,我知道为什么我以前的代码不适合您。这是因为您的xml已经声明了名称空间(xmlns)。解决方案是在搜索要删除的节点时使用LocalName,这将搜索节点名,同时忽略其名称空间。下面的示例显示如何删除所有“info”节点:
基于您的编辑:
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);
}
是否有一个特定的原因使您无法创建一个
XmlDocument
实例,调用LoadXml()
,并处理它?我这样问是因为您编写了“非XML对象”。在返回XML(参数)的函数中,它正在创建一个XML对象
,但将其作为字符串
xmlObject.InnerXml
返回。我无法更改此基本函数,因此我只想修复我正在使用的字符串。我建议您无论如何(重新)使用该字符串构建一个XmlDocument。尝试过它…使用xmlDoc。选择SingleNode(“tagB”)代码>返回NullXPath错误。。。请尝试xmlDoc.SelectSingleNode(“/tagA/tagB”)
或xmlDoc.SelectSingleNode(“/tagB”)
。感谢您的回答,问题是
每次都在不同的地方,我不能在不知道所有父节点的情况下找到它吗?“//tagB”是贪婪的xpath意思;把任何元素带到任何地方。因此,即使tagB嵌套在不同级别的多个元素中,它也能工作。@Dima请参阅我的更新。如果您检查了是否从S中删除,那么是的,它没有,但是通过添加S=doc.ToString()它会删除代码>结尾。@Dima我用一个包含属性的xml进行了测试,程序仍在运行。让我知道你的xml,如果它仍然不为你工作它仍然不工作,我把xml添加到我的question@Dima更新了我的答案。试试看,它对我有用。
var doc = XDocument.Parse(S);
var nodeToRemove = doc.Descendants().Where(o => o.Name.LocalName == "info");
nodeToRemove.Remove();
S = doc.ToString();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(S);
var nodeA = xmlDoc.SelectSingleNode("/tagA");
var nodeB = nodeA.SelectSingleNode("tagB");
nodeA.RemoveChild(nodeB);
var bees = xmlDoc.SelectNodes("//tagB");
foreach (XmlNode bee in bees) {
var parent = bee.ParentNode;
parent.RemoveChild(bee);
}