1

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

4

5 回答 5

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);
于 2013-09-06T06:56:36.143 回答
1

使用 Linq 转 XML

var xDoc = XDocument.Load(fname);

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

xDoc.Save(fname);
于 2013-09-06T06:53:17.687 回答
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

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

于 2013-09-06T07:02:44.690 回答
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");
        }
于 2013-09-06T06:58:35.763 回答
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");

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

于 2013-09-06T06:54:33.287 回答