复制节点并将其另存为新的 XML 文件 C#
本文关键字:XML 文件 另存为 节点 复制 | 更新日期: 2023-09-27 18:30:26
我是新手,这是我关于stackoverflow的第一个问题,所以请耐心等待。
我有以下 xml 文件
<?xml version="1.0" encoding="utf-8"?>
<items>
<superitem>
<item id="10" name="Ten"
description="This is number ten">
<attribute name="weight" value="1" />
<attribute name="capacity" value="80" />
</item>
<item id="20" name="Twenty"
description="This is might be number twenty">
<attribute name="weight" value="1" />
<attribute name="opaque" value="11" />
<uncertain>
<uncertainity name="might" level="Eighty Twenty."/>
</uncertain>
</item>
</superitem>
</items>
在代码中,我正在尝试复制id = 20的节点
newItem.SelectSingleNode("/items/superitem/item[@id='20']")
并将该唯一节点保存到另一个 xml 文件中。所以我正在尝试获取这样的 xml
<?xml version="1.0" encoding="utf-8"?>
<items>
<superitem>
<item id="20" name="Twenty"
description="This is might be number twenty">
<attribute name="weight" value="1" />
<attribute name="opaque" value="11" />
<uncertain>
<uncertainity name="might" level="Eighty Twenty."/>
</uncertain>
</item>
</superitem>
</items>
我尝试将该节点导入该 xml 的最后一个子项之后的 xml 文件,我可以这样做。如果我需要仅使用该节点创建新的 xml 文件,该怎么办?输出 xml 与我上面提到的完全相同??
使用 XElement (XLinq) 要容易得多。
XElement oldDoc = XElement.Load(filename1);
//XElement items = oldDoc.XPathSelectElements("/items/superitem/item[@id='20']");
//XElement newDoc = new XElelement("items", new XElement("superitem", items));
// Because of using an XElement as toplevel (and not XDocumet),
// the XPath has to start lower. And a Singular result is more to the point.
var item = doc.XPathSelectElement("//superitem/item[@id='20']");
XElement newDoc = new XElelement("items", new XElement("superitem", item));
newDoc.Save(fileName2);
使用 linq to xml
var xDoc = XDocument.Load(fname);
foreach (var item in xDoc.XPathSelectElements("/items/superitem/item[@id!='20']"))
item.Remove();
xDoc.Save(fname);
一个看起来很糟糕但有效的 C#/.NET 2.0 解决方案,如果有人需要它:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename); // path to the .xml file
XmlNode selectedNode = xmlDoc.SelectSingleNode("/items/superitem/item[@id='20']");
XmlDocument newXmlDoc = new XmlDocument();
XmlDeclaration declaration = newXmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
newXmlDoc.AppendChild(declaration);
XmlNode itemsNode = newXmlDoc.CreateElement("items");
newXmlDoc.AppendChild(itemsNode);
XmlNode superitemNode = newXmlDoc.CreateElement("superitem");
itemsNode.AppendChild(superitemNode);
XmlNode itemNode = newXmlDoc.ImportNode(selectedNode, true);
superitemNode.AppendChild(itemNode);
newXmlDoc.Save(outputFileName); // name of the new .xml file
如果您不需要史前代码,建议使用其他答案。 ;)
一个快速的解决方案是删除除要保留的元素之外的所有元素,然后保存到新文件:
var xml = XDocument.Load(@"c:'temp'input.xml");
xml.Element("items")
.Element("superitem")
.Elements()
.Where(x => x.Attribute("id").Value != "20")
.Remove();
xml.Save(@"c:'temp'output.xml");
请注意,这不会对缺失的节点等执行任何防御性检查。它假设它将始终获得您在示例中显示的内容 - 通常不是生产代码的安全假设。
Linq to xml是惊人的。
下面是一些示例代码,用于获取超级项并将其存储在新文件中。
//Load the current xml
var Document = new XDocument();
Document = XDocument.Load(AppDomain.CurrentDomain.BaseDirectory + @"MyXmlFile.xml");
//Get the Superitem based on id attribute (you'll want to do some checks to make sure that the xml has the relevent <superitem> node
XElement superitem = Document.Root.Element("superitem").Elements().FirstOrDefault(x => (int?)x.Attribute("id") == 10);
//check a superitem with the id was found
if (superitem != null)
{
//Create New Document:
var newDocument = new XDocument();
newDocument.Declaration =
new XDeclaration("1.0", "utf-8", null);
//Create Root node (items)
XElement root = new XElement("items");
newDocument.Add(root);
//Add the super item to the root.
root.Add(new XElement("superitem", superitem));
//Save
newDocument.Save(AppDomain.CurrentDomain.BaseDirectory + @"SuperItem.xml");
}