给定本地xml文件:
<products>
<product id="p1">
<name>Delta</name>
<price>800</price>
<stock>4</stock>
<country>Denmark</country>
</product>
<product id="p2">
<name>Golf</name>
<price>1000</price>
<stock>5</stock>
<country>Germany</country>
</product>
<product id="p3">
<name>Alfa</name>
<price>1200</price>
<stock>19</stock>
<country>Germany</country>
</product>
<product id="p4">
<name>Foxtrot</name>
<price>1500</price>
<stock>5</stock>
<country>Australia</country>
</product>
<product id="p5">
<name>Tango</name>
<price>1225</price>
<stock>3</stock>
<country>Japan</country>
</product>
</products>
我试图将产品节点'p1'中的price元素替换为:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System;
using System.Xml.XPath;
using System.Xml.Linq;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"products.xml");
Console.WriteLine("\n\nDisplay the initial XML...");
xmlDoc.Save(Console.Out);
//Create an XmlNamespaceManager for resolving namespaces.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("products", "product");
// replace the node with a new one
//Select the profile node with the matching attribute value.
XmlNode product;
XmlElement root = xmlDoc.DocumentElement;
product = root.SelectSingleNode("descendant::product[id='p1']", nsmgr);
//Create a new price element.
XmlElement oldElem = xmlDoc.CreateElement("price");
oldElem.InnerText = "800";
//Create a new price element.
XmlElement newElem = xmlDoc.CreateElement("price");
newElem.InnerText = "125";
//Replace the price element.
root.ReplaceChild(newElem, root.FirstChild);
Console.WriteLine("\n\nDisplay the modified XML...");
xmlDoc.Save(Console.Out);
// save the document with the revised node
xmlDoc.Save(@"products2.xml");
问题是新节点(price)元素被简单地添加到产品p1节点,当保存到磁盘时,该节点将丢弃所有p1。我做错了什么?
答案 0 :(得分:1)
主要问题在
product = root.SelectSingleNode("descendant::product[id='p1']", nsmgr);
因为你没有在下面使用变量。
下一期问题出现在[id='p1']
中,因为您正在像元素一样访问ID,但它应该是一个属性。请改用[@id='p1']
。
其他事项:
<price>
节点的内部文本,而不是替换整个元素。oldNode
。该节点已存在。newElem
未使用。建议你的风格修复:
using System;
using System.Xml;
namespace XmlUpdateNode
{
class Program
{
static void Main()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"products.xml");
Console.WriteLine("\n\nDisplay the initial XML...");
xmlDoc.Save(Console.Out);
// replace the node with a new one
//Select the profile node with the matching attribute value.
var product = xmlDoc.SelectSingleNode("descendant::product[@id='p1']");
//Create a new price element.
XmlElement elem = xmlDoc.CreateElement("price");
elem.InnerText = "125";
//Replace the price element.
product.ReplaceChild(elem, product.FirstChild.NextSibling);
Console.WriteLine("\n\nDisplay the modified XML...");
xmlDoc.Save(Console.Out);
// save the document with the revised node
xmlDoc.Save(@"products2.xml");
}
}
}
直接替换price元素中的文本更短:
using System;
using System.Xml;
namespace XmlUpdateNode
{
class Program
{
static void Main()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"products.xml");
Console.WriteLine("\n\nDisplay the initial XML...");
xmlDoc.Save(Console.Out);
// replace the price directly
var product = xmlDoc.SelectSingleNode("descendant::product[@id='p1']/price");
product.InnerText = "125";
Console.WriteLine("\n\nDisplay the modified XML...");
xmlDoc.Save(Console.Out);
// save the document with the revised node
xmlDoc.Save(@"products2.xml");
}
}
}
答案 1 :(得分:0)
创建节点并将其附加到代码中的产品节点,而不是创建元素。
<job-xml>
你可以重复上面的代码。您希望在产品节点下使用的节点。
答案 2 :(得分:0)
如果我理解正确,您希望更新price
中p1
的值。如果是这样,LINQ会很简单。
XDocument xmlDoc = XDocument.Load(@"products.xml");
var product = xmlDoc.Descendants("product")
.Where(item => item.Attribute("id").Value == "p1").FirstOrDefault();
product.Element("price").Value = "125"; //new price will be 125
如果您随后检查xmlDoc
变量,则会使用价格为p1
的{{1}}进行更新,以便您可以将其保存。当然,您可以使用LINQ创建泛型方法,以便更容易替换任何节点,但上面应该会想到一种方法。