使用LINQ交换元素

时间:2012-06-07 19:18:27

标签: c# xml linq

我有一个以下格式的xml文档:

<body>
    <par id = "1">
      <prop type="Content">One</prop>
      <child xml:id="1">
        <span>This is span 1</span>
      </child>
      <child xml:id="2">
        <span>This is span 2</span>
      </child>
    </par>
</body>

我对使用LINQ不太熟悉,我想用它来交换上面代码的元素。 (I.E.,我想搬家

<span>This is span 2</span>

进入

<child xml:id="1"></child>

元素树,反之亦然)

我正在查看http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b的示例,但我真的希望在正确的方向上进行额外的推动(老实说,我很难确定从哪里开始!)。

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用Linq to sml Query

选择特定元素
   var  retmodule = (from c in xdoc.Elements("body").Elements("par").Elements("child").
                             where c.Attribute("xml:id").Value == 2
                             select new 
                             {
                              c.Element("span").Value
                             }).SingleOrDefault();

然后使用xpath和xml库的组合插入它

XElement parentXElement = xmldoc.XPathSelectElement("products");
XElement refXElement = xdoc.XPathSelectElement("body/par/child [@xml:id = '2']");
XElement newXElement = new XElement("span", retmodule.ToString());
refXElement.AddAfterSelf(newXElement);
xdoc.Save();

答案 1 :(得分:1)

我相信这会做你想要的:

using System;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"
<body>
    <par id = ""1"">
      <prop type=""Content"">One</prop>
      <child xml:id=""1"">
        <span>This is span 1</span>
      </child>
      <child xml:id=""2"">
        <span>This is span 2</span>
      </child>
    </par>
</body>";
            XDocument doc = XDocument.Parse(xml);
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(doc.CreateNavigator().NameTable);
            namespaceManager.AddNamespace("xml", "http://www.w3.org/XML/1998/namespace");
            XElement span1 = doc.Root.XPathSelectElement(@"/body/par/child[@xml:id = ""1""]/span[1]", namespaceManager);
            XElement span2 = doc.Root.XPathSelectElement(@"/body/par/child[@xml:id = ""2""]/span[1]", namespaceManager);

            span1.ReplaceWith(span2);
            span2.ReplaceWith(span1);

            Console.WriteLine(doc);
        }
    }
}

答案 2 :(得分:1)

可以使用LINQ,但它真的意味着查询,而不是修改。从技术上讲,你可以写一个查询来给你你想要的结果,但它会相当丑陋。

我建议将字符串加载到XMLDocument中并使用XPath交换节点:

    private static string swap(string xml)
    {
        XmlDocument xDoc = new XmlDocument();
        xDoc.LoadXml(xml);

        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xDoc.NameTable);
        namespaceManager.AddNamespace("xml", "http://www.w3.org/XML/1998/namespace");  

        var node1 = xDoc.SelectSingleNode(@"//child[@xml:id=""1""]",namespaceManager);
        var node2 = xDoc.SelectSingleNode(@"//child[@xml:id=""2""]",namespaceManager);

        var temp = node1.InnerXml;
        node1.InnerXml = node2.InnerXml;
        node2.InnerXml = temp;

        return xDoc.OuterXml;
    }

请注意,您需要使用XmlNamespaceManager来考虑文档中的“xml”命名空间(我假设它是在其他地方定义的)。