复制节点并将其另存为新的xml文件c#

时间:2013-09-06 06:30:19

标签: c# xml

我是一个新手,这是我关于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与我上面提到的完全一样??

5 个答案:

答案 0 :(得分:3)

使用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);

答案 1 :(得分:1)

使用Linq to Xml

var xDoc = XDocument.Load(fname);

foreach (var item in xDoc.XPathSelectElements("/items/superitem/item[@id!='20']"))
    item.Remove();

xDoc.Save(fname);

答案 2 :(得分:1)

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

如果您不需要史前代码,建议使用其他答案。 ;)

答案 3 :(得分:0)

快速解决方案是删除除要保留的元素之外的所有元素,然后保存到新文件:

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

请注意,这不会对丢失的节点执行任何防御性检查等。它假设它将始终获得您在示例中显示的内容 - 通常不是生产代码的安全假设。

答案 4 :(得分:0)

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