Change the node names in an XML file using C#

后端 未结 8 1830
南笙
南笙 2020-12-09 17:51

I have a huge bunch of XML files with the following structure:


  someContent
  someType
&         


        
相关标签:
8条回答
  • 2020-12-09 18:10

    I used this method to rename the node:

    /// <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);
    }
    
    0 讨论(0)
  • 2020-12-09 18:11

    (1.) The [XmlElement / XmlNode].Name property is read-only.

    (2.) The XML structure used in the question is crude and could be improved.

    (3.) Regardless, here is a code solution to the given question:

    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: I came here looking for a nicer way of renaming a node/element; I'm still looking.

    0 讨论(0)
  • 2020-12-09 18:12

    Load it in as a string and do a replace on the whole lot..

        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")
    
    0 讨论(0)
  • 2020-12-09 18:15

    I'll answer the higher question: why are you trying this using XmlDocument?

    I Think the best way to accomplish what you aim is a simple XSLT file
    that match the "CONTENTSTUFF" node and output a "CONTENT" node...

    don't see a reason to get such heavy guns...

    Either way, If you still wish to do it C# Style,
    Use XmlReader + XmlWriter and not XmlDocument for memory and speed purposes. XmlDocument store the entire XML in memory, and makes it very heavy for Traversing once...

    XmlDocument is good if you access the element many times (not the situation here).

    0 讨论(0)
  • 2020-12-09 18:21

    The XML you have provided shows that someone completely misses the point of XML.

    Instead of having

    <stuff1>
       <content/>
    </stuff1>
    

    You should have:/

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

    Now you would be able to traverse the document using Xpath (ie, //stuff[id='1']/content/) The names of nodes should not be used to establish identity, you use attributes for that.

    To do what you asked, load the XML into an xml document, and simply iterate through the first level of child nodes renaming them.

    PseudoCode:

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

    However, I'd strongly recommend you actually fix the XML so that it is useful, instead of wreck it further.

    0 讨论(0)
  • 2020-12-09 18:25

    The easiest way I found to rename a node is:

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

    Don't include the opening < to ensure that the closing </OldName> tag is renamed as well.

    0 讨论(0)
提交回复
热议问题