使用 C# 更改 XML 文件中的节点名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/475293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change the node names in an XML file using C#
提问by sundeep
I have a huge bunch of XML files with the following structure:
我有一大堆具有以下结构的 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>
...
...
I need to change the each of the "Content" node names to StuffxContent; basically prepend the parent node name to the content node's name.
我需要将每个“内容”节点名称更改为 StuffxContent;基本上将父节点名称添加到内容节点的名称之前。
I planned to use the XMLDocument
class and figure out a way, but thought I would ask if there were any better ways to do this.
我计划使用XMLDocument
该类并找出一种方法,但我想我会问是否有更好的方法来做到这一点。
采纳答案by FlySwat
The XML you have provided shows that someone completely misses the point of XML.
您提供的 XML 表明有人完全忽略了 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.
现在您将能够使用 Xpath 遍历文档(即,//stuff[id='1']/content/)节点的名称不应该用于建立身份,您可以使用属性来实现。
To do what you asked, load the XML into an xml document, and simply iterate through the first level of child nodes renaming them.
要执行您的要求,请将 XML 加载到 xml 文档中,然后简单地遍历第一级子节点并重命名它们。
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.
但是,我强烈建议您实际修复 XML 以使其有用,而不是进一步破坏它。
回答by ZombieSheep
Perhaps a better solution would be to iterate through each node, and write the information out to a new document. Obviously, this will depend on how you will be using the data in future, but I'd recommend the same reformatting as FlySwat suggested...
也许更好的解决方案是遍历每个节点,并将信息写入新文档。显然,这将取决于您将来如何使用数据,但我建议使用与 FlySwat 建议的相同的重新格式化...
<stuff id="1">
<content/>
</stuff>
I'd also suggest that using the XDocument that was recently added would be the best way to go about creating the new document.
我还建议使用最近添加的 XDocument 是创建新文档的最佳方式。
回答by Omar
(1.) The [XmlElement / XmlNode].Name property is read-only.
(1.) [XmlElement / XmlNode].Name 属性是只读的。
(2.) The XML structure used in the question is crude and could be improved.
(2.)问题中使用的XML结构很粗糙,可以改进。
(3.) Regardless, here is a code solution to the given question:
(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: I came here looking for a nicer way of renaming a node/element; I'm still looking.
PS:我来这里是为了寻找一种更好的重命名节点/元素的方法;我还在找。
回答by Tomer W
I'll answer the higher question: why are you trying this using XmlDocument
?
我会回答更高的问题:你为什么要尝试这个使用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...
我认为实现您的目标的最佳方法是一个简单的 XSLT 文件
,该文件与“CONTENTSTUFF”节点匹配并输出“CONTENT”节点...
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...
无论哪种方式,如果您仍然希望
使用C# 样式,请使用XmlReader
+XmlWriter
而不是XmlDocument
出于内存和速度目的。
XmlDocument
将整个 XML 存储在内存中,这使得遍历一次非常繁重......
XmlDocument is good if you access the element many times (not the situation here).
如果您多次访问该元素(不是这里的情况),则 XmlDocument 很好。
回答by Marc
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.
不要包括开头<
以确保结束</OldName>
标签也被重命名。
回答by timothy
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")
回答by Acubo
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);
}