Обновление или вставка узла в документ XML - PullRequest
0 голосов
/ 14 мая 2009

Я новичок в XML и XPath в C #. Вот пример моего документа XML:

 <root>
   <folder1>
   ...
   <folderN>
      ...
      <nodeMustExist>...
      <nodeToBeUpdated>some value</nodeToBeUpdated>
  ....
 </root>

Мне нужно обновить значение nodeToBeUdpated, если узел существует, или добавить этот узел после nodeMustExist, если nodeToBeUpdated не существует. Прототип функции выглядит примерно так:

void UpdateNode(
                  xmlDocument xml, 
                  string nodeMustExist, 
                  string nodeToBeUpdte, 
                  string newVal
               )
{
   /*

   search for XMLNode with name = nodeToBeUpdate in xml 
   to XmlNodeToBeUpdated (XmlNode type?)
   if (xmlNodeToBeUpdated != null)
   {
      xmlNodeToBeUpdated.value(?) = newVal;
   }
   else
   {
      search for nodeMustExist in xml to xmlNodeMustExist obj
      if ( xmlNodeMustExist != null )
      {
          add xmlNodeToBeUpdated as next node
          xmlNodeToBeUpdte.value = newVal;
       }
    }

   */
}

Может быть, есть другой лучший и упрощенный способ сделать это. Любой совет?

Кстати, если nodeToBeUpdated появляется более одного раза в других местах, я просто хочу обновить первое.

Ответы [ 3 ]

1 голос
/ 14 мая 2009

Выражение XPath, которое выбирает все экземпляры <nodeToBeUpdated>, будет таким:

/root/folder[nodeMustExist]/nodeToBeUpdated

или, в более общем виде:

/root/folder[*[name() = 'nodeMustExist']]/*[name() = 'nodeToBeUpdated']

подходит для:

void UpdateNode(xmlDocument xml, 
                string nodeMustExist, 
                string nodeToBeUpdte, 
                string newVal)
{
  string xPath = "/root/folder[*[name() = '{0}']]/*[name() = '{1}']";
  xPath = String.Format(xPath, nodeMustExist, nodeToBeUpdte);

  foreach (XmlNode n in xml.SelectNodes(xPath))
  {
    n.Value = newVal;
  }
}
1 голос
/ 14 мая 2009

Обновление всех узлов в папке:

public void UpdateNodes(XmlDocument doc, string newVal)
        {
            XmlNodeList folderNodes = doc.SelectNodes("folder");

            if (folderNodes.Count > 0)
            foreach (XmlNode folderNode in folderNodes)
            {
                XmlNode updateNode = folderNode.SelectSingleNode("nodeToBeUpdated");
                XmlNode mustExistNode = folderNode.SelectSingleNode("nodeMustExist"); ;
                if (updateNode != null)
                { 
                    updateNode.InnerText = newVal;
                }
                else if (mustExistNode != null)
                {
                    XmlNode node = folderNode.OwnerDocument.CreateNode(XmlNodeType.Element, "nodeToBeUpdated", null);
                    node.InnerText = newVal;
                    folderNode.AppendChild(node);
                }

            }
        }

Если вы хотите обновить определенный узел, вы не можете передать строку nodeToBeUpdte, но вам придется передать XmlNode XmlDocument. Я пропустил передачу имен узлов в функцию, так как имена узлов вряд ли изменятся и могут быть жестко закодированы. Однако вы можете передать их функциям и использовать строки вместо жестко закодированных имен узлов.

0 голосов
/ 14 мая 2009

Посмотрите на метод SelectSingleNode Документ MSDN

ваш xpath хочет быть что-то вроде "// YourNodeNameHere";

как только вы нашли этот узел, вы можете затем пройти обратно вверх по дереву, чтобы добраться до узла 'nodeMustExist':

XmlNode nodeMustExistNode = yourNode.Parent["nodeMustExist];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...