Измените имена 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/; Я все еще смотрю.

Ответ 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")