Измените имена node в 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" node на StuffxContent; в основном добавьте родительское имя node к содержимому node.
Я планировал использовать класс XMLDocument
и выяснить способ, но подумал, что я спрошу, есть ли какие-нибудь лучшие способы сделать это.
Ответы
Ответ 1
Представленный вами XML показывает, что кто-то полностью пропускает точку XML.
Вместо
<stuff1>
<content/>
</stuff1>
Вы должны иметь:/
<stuff id="1">
<content/>
</stuff>
Теперь вы сможете перемещаться по документу с помощью Xpath (т.е.//stuff [id = '1']/content/) Имена узлов не должны использоваться для установления личности, вы используете для этого атрибуты.
Чтобы сделать то, что вы спросили, загрузите XML в XML-документ и просто перейдете к первому уровню дочерних узлов, переименовав их.
псевдокод:
foreach (XmlNode n in YourDoc.ChildNodes)
{
n.ChildNode[0].Name = n.Name + n.ChildNode[0].Name;
}
YourDoc.Save();
Тем не менее, я настоятельно рекомендую вам исправить XML, чтобы он был полезен, а не разрушил его дальше.
Ответ 2
(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: Я пришел сюда, пытаясь переименовать элемент node/; Я все еще смотрю.
Ответ 3
Здесь хороший бит кода, который я нашел для метода RenameNode():
http://www.goodgord.com/2006/10/how-to-rename-xml-node-in-c.html
Ответ 4
Самый простой способ переименовать node:
xmlNode.InnerXmL = newNode.InnerXml.Replace("OldName>", "NewName>")
Не включайте открывание <
, чтобы тег закрытия </OldName>
также был переименован.
Ответ 5
Возможно, лучшим решением будет итерация через каждый node и запись информации в новый документ. Очевидно, это будет зависеть от того, как вы будете использовать данные в будущем, но я бы порекомендовал тот же переформатирование, что предложил FlySwat...
<stuff id="1">
<content/>
</stuff>
Я бы также предположил, что использование недавно добавленного XDocument будет лучшим способом для создания нового документа.
Ответ 6
Я отвечу на более высокий вопрос: почему вы пытаетесь использовать это с помощью XmlDocument
?
Я думаю, что лучший способ добиться того, что вы намереваетесь, - это простой XSLT файл
которые соответствуют "CONTENTSTUFF" node и выводят "CONTENT" node...
не видят причины получить такие тяжелые пушки...
В любом случае, если вы все еще хотите сделать это С# Style,
Используйте XmlReader
+ XmlWriter
, а не XmlDocument
для целей памяти и скорости.
XmlDocument
хранит весь XML в памяти и делает его очень тяжелым для Traversing один раз...
XmlDocument хорош, если вы обращаетесь к элементу много раз (не здесь).
Ответ 7
Загрузите его в виде строки и замените на всю лот.
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")