在XML中添加新节点时出现问题

本文关键字:问题 节点 XML 添加 新节点 | 更新日期: 2023-09-27 18:24:08

我正试图在XML文件中添加一个新节点,但由于导航器的当前位置,我收到了InvalidOperationException。

这是我的XML文件:

<?xml version="1.0" encoding="utf-8" ?> 
<dictionary xmlns="RecnikSema.xsd">
<sentiments>
  <sentiment word="napustiti">-2</sentiment>
</sentiments>  
</dictionary>

和模式:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="dictionary">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="sentiments">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="sentiment">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="word"/>
                      <xs:attribute type="xs:double" name="value"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

我用来添加新节点的C#代码如下:

XmlDocument dictionary= new XmlDocument();
dictionary.Load(@"C:'Users'Luka'Documents'Visual Studio 2013'Projects'TSA'TSA'Dictionary.xml");
XPathNavigator navigator = dictionary.CreateNavigator();
navigator.MoveToChild("dictionary", @"C:'Users'Luka'Documents'Visual Studio 2013'Projects'TSA'TSA'RecnikSema.xsd");
navigator.MoveToChild("sentiments", @"C:'Users'Luka'Documents'Visual Studio 2013'Projects'TSA'TSA'RecnikSema.xsd");
navigator.MoveToChild("sentiment", @"C:'Users'Luka'Documents'Visual Studio 2013'Projects'TSA'TSA'RecnikSema.xsd");
navigator.InsertAfter("<sentiment word='"" + token + "'">" + value + "</sentiment>");

异常发生在InsertAfter的最后一行。

我在这里做错了什么?

在XML中添加新节点时出现问题

为什么不使用XDocument让它变得简单。

C#的新版本中有这样一个类,它可以很容易地操作Xml。因此,它也支持Xml Linq。

以下是可能对您有用的快速解决方案。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument document = XDocument.Load(@"C:'Users'amit'SkyDrive'code'WebApplication1'ConsoleApplication1'xml.xml");
            XElement root = new XElement("sentiment");
            root.Value = "3";
            root.Add(new XAttribute("word", "napustiti"));
            XNamespace nsSys = "RecnikSema.xsd";
            document.Element(nsSys + "dictionary").Element(nsSys + "sentiments").Add(root);
            document.Save("c:'newFile.xml");
        }
    }
}

我认为您的问题是您没有指定maxOccurs(默认值为1),并且您已经准备好添加了on元素。看见http://www.w3schools.com/schema/el_sequence.asp

maxOccurs可选。指定序列的最大次数元素可以出现在父元素中。该值可以是任何数字>=0,或者如果不想对最大数字设置限制,请使用"无界"。默认值为1

因此,您的多重情感解决方案:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="dictionary">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="sentiments">
          <xs:complexType>
            <xs:sequence maxOccurs="unbounded">
              <xs:element name="sentiment">
                <xs:complexType>
                  <xs:simpleContent>
                    <xs:extension base="xs:string">
                      <xs:attribute type="xs:string" name="word"/>
                      <xs:attribute type="xs:double" name="value"/>
                    </xs:extension>
                  </xs:simpleContent>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

我更喜欢使用Microsoft xsd工具生成CLR类->http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx并使用XMLSerializer->http://msdn.microsoft.com/de-de/library/system.xml.serialization.xmlserializer(v=vs.110).aspx

MoveToChild()中,第二个参数是XML名称空间,而不是文档的位置。在您的情况下,您已经设置了xmlns="RecnikSema.xsd"。这意味着MoveToChild找不到匹配项,所以当您到达insertAfter时,当前节点仍然是根节点<dictionary>,它尝试创建这样的XML:

<?xml version="1.0" encoding="utf-8" ?> 
<dictionary xmlns="RecnikSema.xsd">
    <sentiment word="napustiti">-2</sentiment>
</dictionary>
<sentiment word="foo">5</sentiment>

这有2个根元素,所以你会得到错误

相反,您需要传递"RecnikSema.xsd"作为参数。:

navigator.MoveToChild("dictionary", "RecnikSema.xsd");
navigator.MoveToChild("sentiments", "RecnikSema.xsd");
navigator.MoveToChild("sentiment", "RecnikSema.xsd");

我不确定你是不是想把它设置为命名空间,因为它是Schema文件,所以也许你是这个意思?:

XML

<?xml version="1.0" encoding="utf-8" ?> 
<dictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="RecnikSema.xsd">
    <sentiments>
        <sentiment word="napustiti">-2</sentiment>
    </sentiments>
</dictionary>

C#

XmlDocument dictionary= new XmlDocument();
dictionary.Load(@"C:'Users'Luka'Documents'Visual Studio 2013'Projects'TSA'TSA'Dictionary.xml");
XPathNavigator navigator = dictionary.CreateNavigator();
navigator.MoveToChild("dictionary", "");
navigator.MoveToChild("sentiments", "");
navigator.MoveToChild("sentiment", "");
navigator.InsertAfter("<sentiment word='"" + token + "'">" + value + "</sentiment>");