Pregunta

He encontrado algunos ejemplos sobre este tema. Algunos de los ejemplos gived un método para modificar atributo con SelectNodes() o SelectSingleNode(), y otros gived el método para modificar atributo con someElement.SetAttribute("attribute-name", "new value");

Pero todavía confundido que cómo construir la relación, si sólo se utiliza un XpathNodeItterator it?

asumieron que yo define como a continuación,

System.Xml.XPath.XPathDocument doc = new XPathDocument(xmlFile);
System.Xml.XPath.XPathNavigator nav = doc.CreateNavigator();
System.Xml.XPath.XPathNodeIterator it;

it = nav.Select("/Equipment/Items/SubItmes");
while (it.MoveNext())
{
   name = it.Current.GetAttribute("name ", it.Current.NamespaceURI);
   int vidFromXML = int.Parse(it.Current.GetAttribute("vid", it.Current.NamespaceURI));
   if (vidFromXML = vid)
   { 
    // How can I find the relation between it and element and node? I want to modify name attribute value. 
   }
}

¿Hay un método como it.setAttribute(name, "newValue")?

¿Fue útil?

Solución

MSDN : "Un objeto XPathNavigator se crea de una clase que implementa la interfaz IXPathNavigable tales como las clases XPathDocument y XmlDocument. XPathNavigator objetos creados por objetos XPathDocument están de sólo lectura mientras XPathNavigator objetos creados por objetos XmlDocument se pueden editar. un XPathNavigator se determina de sólo lectura del objeto o estado editable mediante la propiedad CanEdit de la clase XPathNavigator ".

Por lo tanto, en primer lugar, usted tiene que utilizar XmlDocument, no XPathDocument, si desea establecer un atributo.

Un ejemplo de cómo modificar datos XML utilizando un XPathNavigator utilizando el método CreateNavigator de un XmlDocument, se muestra aquí .

Como se verá en el ejemplo, hay un método FijarValor en el objeto it.Current.

Así es como usted lo haría para su código, con algunas ligeras modificaciones:

        int vid = 2;
        var doc = new XmlDocument();
        doc.LoadXml("<Equipment><Items><SubItems  vid=\"1\" name=\"Foo\"/><SubItems vid=\"2\" name=\"Bar\"/></Items></Equipment>");
        var nav = doc.CreateNavigator();

        foreach (XPathNavigator it in nav.Select("/Equipment/Items/SubItems"))
        {
            if(it.MoveToAttribute("vid", it.NamespaceURI)) {
                int vidFromXML = int.Parse(it.Value);                    
                if (vidFromXML == vid)
                {
                    // if(it.MoveToNextAttribute() ... or be more explicit like the following:

                    if (it.MoveToParent() && it.MoveToAttribute("name", it.NamespaceURI))
                    {
                        it.SetValue("Two");
                    } else {
                        throw new XmlException("The name attribute was not found.");
                    }                
                }
            } else {
                    throw new XmlException("The vid attribute was not found.");
            }
        }

Otros consejos

Me escribió un método de extensión que proporciona un método para cualquier SetAttribute XPathNavigator:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace My.Shared.Utilities {
    public static class XmlExtensions {
        public static void SetAttribute(this XPathNavigator nav, string localName, string namespaceURI, string value) {
            if (!nav.MoveToAttribute(localName, namespaceURI)) {
                throw new XmlException("Couldn't find attribute '" + localName + "'.");
            }
            nav.SetValue(value);
            nav.MoveToParent();
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top