Изменение существующего контента XML в C #
-
26-09-2019 - |
Вопрос
Я нашел несколько примеров этой темы. Некоторые из примеров приведены метод для модификации атрибута с SelectNodes()
или SelectSingleNode()
, и другие создали метод изменять атрибут с someElement.SetAttribute("attribute-name", "new value");
Но я все еще запутался, как построить отношение, если я использовал только XpathNodeItterator it
?
Предполагается, что я определил как ниже,
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.
}
}
Есть ли метод, как it.setAttribute(name, "newValue")
?
Решение
От MSDN: «Объект XPathnavigator создан из класса, который реализует интерфейс IxPathnavigable, такой как XPathDocument и классы XMLDocument. Объекты XPathnavigator, созданные объектами XPathdocument, являются только для чтения В то время как объекты XPathnavigator, созданные объектами XMLDocument, могут быть отредактированы. Только для чтения или редактируемого объекта XPathnavigator или редактируемый статус определяется с помощью свойства Canedit класса XPathnavigator. "
Итак, прежде всего, вы должны использовать XMLDocument, а не XPathDocument, если вы хотите установить атрибут.
Пример того, как изменить данные XML с использованием XPathnavigator с использованием метода CreateNavigator XMLDocument, здесь.
Как вы увидите из примера, есть метод SetValue. На вашем это. Текущий объект.
Вот как вы сделаете это для вашего кода, с небольшими модификациями:
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.");
}
}
Другие советы
Я написал метод расширения, который обеспечивает 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();
}
}
}