使用C#将XML节点转换为属性

时间:2011-09-06 15:52:33

标签: c# xml

我有一个加载到XMLDocument中的XML字符串,类似于下面列出的字符串:

  <note>
   <to>You</to> 
   <from>Me</from> 
   <heading>TEST</heading> 
   <body>This is a test.</body> 
  </note>

我想将文本节点转换为属性(使用C#),所以它看起来像这样:

<note to="You" from="Me" heading="TEST" body="This is a test." />

任何信息都将不胜感激。

3 个答案:

答案 0 :(得分:2)

Linq to XML非常适合这种东西。如果你愿意,你可以在一行中实现它。只需获取子节点名称及其各自的值,然后将所有这些“键值对”添加为属性。

MSDN文档:http://msdn.microsoft.com/en-us/library/bb387098.aspx

答案 1 :(得分:0)

像seldon建议的那样,LINQ to XML将更适合这类任务。

但这是使用XmlDocument做到这一点的方法。没有声称这是万无一失的(没有测试过),但它确实适用于你的样品。

XmlDocument input = ...

// Create output document.
XmlDocument output = new XmlDocument();

// Create output root element: <note>...</note>
var root = output.CreateElement(input.DocumentElement.Name);

// Append attributes to the output root element
// from elements of the input document.
foreach (var child in input.DocumentElement.ChildNodes.OfType<XmlElement>())
{
    var attribute = output.CreateAttribute(child.Name); // to
    attribute.Value = child.InnerXml; // to = "You"
    root.Attributes.Append(attribute); // <note to = "You">
}

// Make <note> the root element of the output document.
output.AppendChild(root);

答案 2 :(得分:0)

以下将任何简单的XML叶节点转换为其父级的属性。它作为单元测试实现。将您的XML内容封装到一个input.xml文件中,并检查它是否保存为output.xml。

using System;
using System.Xml;
using System.Linq;
using NUnit.Framework;

[TestFixture]
public class XmlConvert
{
    [TestCase("input.xml", "output.xml")]
    public void LeafsToAttributes(string inputxml, string outputxml)
    {
        var doc = new XmlDocument();
        doc.Load(inputxml);
        ParseLeafs(doc.DocumentElement);
        doc.Save(outputxml);
    }

    private void ParseLeafs(XmlNode parent)
    {
        var children = parent.ChildNodes.Cast<XmlNode>().ToArray();
        foreach (XmlNode child in children)
            if (child.NodeType == XmlNodeType.Element
                && child.Attributes.Count == 0
                && child.ChildNodes.Count == 1
                && child.ChildNodes[0].NodeType == XmlNodeType.Text
                && parent.Attributes[child.Name] == null)
            {
                AddAttribute(parent, child.Name, child.InnerXml);
                parent.RemoveChild(child);
            }
            else ParseLeafs(child);

        // show no closing tag, if not necessary
        if (parent.NodeType == XmlNodeType.Element
            && parent.ChildNodes.Count == 0)
            (parent as XmlElement).IsEmpty = true;
    }

    private XmlAttribute AddAttribute(XmlNode node, string name, string value)
    {
        var attr = node.OwnerDocument.CreateAttribute(name);
        attr.Value = value;
        node.Attributes.Append(attr);
        return attr;
    }
}