Изменить имена узлов в файле XML с помощью C # - PullRequest
14 голосов
/ 24 января 2009

У меня есть огромная куча файлов 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 и найти способ, но подумал, что я спрошу, есть ли лучшие способы сделать это.

Ответы [ 6 ]

53 голосов
/ 14 декабря 2010

(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: я пришел сюда в поисках лучшего способа переименования узла / элемента; Я все еще ищу.

3 голосов
/ 02 октября 2012

Я нашел самый простой способ переименовать узел:

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

Не включайте открывающий <, чтобы убедиться, что закрывающий тег </OldName> также переименован.

0 голосов
/ 24 января 2018

Загрузите его как строку и выполните замену всего лота.

    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 голосов
/ 13 августа 2012

Я отвечу на более высокий вопрос: почему вы пытаетесь это использовать XmlDocument?

Я думаю, что лучший способ достичь цели - это простой XSLT-файл
которые соответствуют узлу "CONTENTSTUFF" и выводят узел "CONTENT" ...

не вижу причин, чтобы получить такие тяжелые орудия ...

В любом случае, если вы все еще хотите сделать это в стиле C #,
Используйте XmlReader + XmlWriter, а не XmlDocument для памяти и скорости. XmlDocument сохраняет весь XML в памяти и делает его очень тяжелым для обхода ...

XmlDocument хорош, если вы обращаетесь к элементу много раз (не ситуация здесь).

0 голосов
/ 23 ноября 2009

Возможно, лучшим решением было бы перебирать каждый узел и записывать информацию в новый документ. Очевидно, это будет зависеть от того, как вы будете использовать данные в будущем, но я бы порекомендовал такое же переформатирование, как предлагал FlySwat ...

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

Я бы также предположил, что использование недавно добавленного XDocument было бы лучшим способом создания нового документа.

0 голосов
/ 24 января 2009

Предоставленный вами 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, чтобы он был полезен, а не разрушать его дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...