使用C#更改XML文件中的节点名称

时间:2009-01-24 01:31:14

标签: c# xml

我有大量具有以下结构的XML文件:

<Stuff1>
  <Content>someContent</name>
  <type>someType</type>
</Stuff1>
<Stuff2>
  <Content>someContent</name>
  <type>someType</type>
</Stuff2>
<Stuff3>
  <Content>someContent</name>
  <type>someType</type>
</Stuff3>
...
...

我需要将每个“Content”节点名称更改为StuffxContent;基本上将父节点名称添加到内容节点的名称。

我计划使用XMLDocument课程并找出方法,但我想我会问是否有更好的方法可以做到这一点。

8 个答案:

答案 0 :(得分:53)

(1。)[XmlElement / XmlNode] .Name属性是只读的。

(2。)问题中使用的XML结构很粗糙,可以改进。

(3。)无论如何,这是给定问题的代码解决方案:

String sampleXml =
  "<doc>"+
    "<Stuff1>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff1>"+
    "<Stuff2>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff2>"+
    "<Stuff3>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff3>"+
  "</doc>";

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sampleXml);

XmlNodeList stuffNodeList = xmlDoc.SelectNodes("//*[starts-with(name(), 'Stuff')]");

foreach (XmlNode stuffNode in stuffNodeList)
{
    // get existing 'Content' node
    XmlNode contentNode = stuffNode.SelectSingleNode("Content");

    // create new (renamed) Content node
    XmlNode newNode = xmlDoc.CreateElement(contentNode.Name + stuffNode.Name);

    // [if needed] copy existing Content children
    //newNode.InnerXml = stuffNode.InnerXml;

    // replace existing Content node with newly renamed Content node
    stuffNode.InsertBefore(newNode, contentNode);
    stuffNode.RemoveChild(contentNode);
}

//xmlDoc.Save

PS:我来到这里寻找一种更好的方式来重命名节点/元素;我还在寻找。

答案 1 :(得分:3)

我发现重命名节点的最简单方法是:

xmlNode.InnerXmL = newNode.InnerXml.Replace("OldName>", "NewName>")

不要包含开头<,以确保重命名结束</OldName>标记。

答案 2 :(得分:0)

也许更好的解决方案是遍历每个节点,并将信息写入新文档。显然,这将取决于您将来如何使用这些数据,但我建议使用与FlySwat建议相同的重新格式化...

<stuff id="1">
    <content/>
</stuff>

我还建议使用最近添加的XDocument是创建新文档的最佳方式。

答案 3 :(得分:0)

我会回答更高的问题:为什么要使用XmlDocument尝试此操作?

我认为实现目标的最佳方法是使用简单的XSLT文件 匹配“CONTENTSTUFF”节点并输出“CONTENT”节点......

没有理由得到这么重的枪......

无论哪种方式,如果你仍然希望这样做C#Style,
出于内存和速度的目的,请使用XmlReader + XmlWriter而非XmlDocumentXmlDocument将整个XML存储在内存中,并使其在Traversing中非常繁重......

如果你多次访问该元素,XmlDocument很好(不是这里的情况)。

答案 4 :(得分:0)

我使用此方法来重命名节点:

/// <summary>
/// Rename Node
/// </summary>
/// <param name="parentnode"></param>
/// <param name="oldname"></param>
/// <param name="newname"></param>
private static void RenameNode(XmlNode parentnode, string oldChildName, string newChildName)
{
    var newnode = parentnode.OwnerDocument.CreateNode(XmlNodeType.Element, newChildName, "");
    var oldNode = parentnode.SelectSingleNode(oldChildName);

    foreach (XmlAttribute att in oldNode.Attributes)
        newnode.Attributes.Append(att);
    foreach (XmlNode child in oldNode.ChildNodes)
        newnode.AppendChild(child);

    parentnode.ReplaceChild(newnode, oldNode);
}

答案 5 :(得分:0)

我不是XML方面的专家,就我而言,我只需要将HTML文件中的所有标签名都设为大写,以便在XmlDocument中使用GetElementsByTagName进行进一步操作。我需要大写的原因是,对于XmlDocument,标记名称区分大小写(因为它是XML),并且我不能保证标记名称中HTML文件的大小写一致。

所以我这样解决了它:我使用XDocument作为中间步骤,您可以在其中重命名元素(即标记名),然后将其加载到XmlDocument中。这是我的VB.NET代码(C#编码将非常相似)。

Dim x As XDocument = XDocument.Load("myFile.html")
For Each element In x.Descendants()
  element.Name = element.Name.LocalName.ToUpper()
Next
Dim x2 As XmlDocument = New XmlDocument()
x2.LoadXml(x.ToString())

就我的目的而言,它工作得很好,尽管我知道在某些情况下,如果要处理纯XML文件,这可能不是解决方案。

答案 6 :(得分:-1)

将其作为字符串加载并在整个批次上进行替换..

    String sampleXml =
  "<doc>"+
    "<Stuff1>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff1>"+
    "<Stuff2>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff2>"+
    "<Stuff3>"+
      "<Content>someContent</Content>"+
      "<type>someType</type>"+
    "</Stuff3>"+
  "</doc>"; 

    sampleXml = sampleXml.Replace("Content","StuffxContent")

答案 7 :(得分:-28)

您提供的XML表明某人完全忽视了XML。

而不是

<stuff1>
   <content/>
</stuff1>

你应该:/

<stuff id="1">
    <content/>
</stuff>

现在您可以使用Xpath遍历文档(即// stuff [id ='1'] / content /)节点的名称不应该用于建立标识,您可以使用属性。< / p>

要执行您的要求,请将XML加载到xml文档中,然后简单地遍历重命名它们的第一级子节点。

伪代码:

foreach (XmlNode n in YourDoc.ChildNodes)
{        
    n.ChildNode[0].Name = n.Name + n.ChildNode[0].Name;
}

YourDoc.Save();

但是,我强烈建议您实际修复XML以使其有用,而不是进一步破坏它。