2013-02-10 8 views
5

Ich versuche, neue Knoten zu einer vorhandenen XML-Datei hinzuzufügen. Ich habe diese Datei mit ersten Testelementen darin:C#, XML, neue Knoten hinzufügen

<?xml version="1.0" encoding="utf-8"?> 
<Root xmlns="http://prpa.org/XMLSchema1.xsd"> 
    <studenti> 
    <student> 
     <ime>test</ime> 
     <prezime>test</prezime> 
     <ocijena>0</ocijena> 
    </student> 
    </studenti> 
    <profesori> 
    <profesor> 
     <ime>test</ime> 
     <prezime>test</prezime> 
    </profesor> 
    </profesori> 
</Root> 

verwenden ich dieses Schema dieses XML-Dokument

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="XMLSchema1" 
    targetNamespace="http://prpa.org/XMLSchema1.xsd" 
    elementFormDefault="qualified" 
    xmlns="http://prpa.org/XMLSchema1.xsd" 
    xmlns:mstns="http://prpa.org/XMLSchema1.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      > 
    <xs:element name='Root'> 
    <xs:complexType> 
     <xs:sequence> 

    <xs:element name="studenti"> 
    <xs:complexType> 
     <xs:sequence>  
    <xs:element name="student"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="ime" type="xs:string"/> 
     <xs:element name="prezime" type="xs:string"/> 
     <xs:element name="ocijena" type="xs:int"/> 
    </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 

    <xs:element name="profesori"> 
    <xs:complexType> 
     <xs:sequence> 
    <xs:element name="profesor"> 
     <xs:complexType> 
     <xs:sequence> 
     <xs:element name="ime" type="xs:string"/> 
     <xs:element name="prezime" type="xs:string"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
    </xs:sequence> 
    </xs:complexType> 
    </xs:element> 

     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 

</xs:schema> 

Jetzt zu erzeugen, ich brauche neuen Knoten hinzuzufügen

<profesor> 
     <ime>test2</ime> 
     <prezime>test2</prezime> 
    </profesor> 

Ich habe es so weit versucht:

XmlDocument xmldoc = new XmlDocument(); 
     xmldoc.Load(Server.MapPath("data/sve.xml")); 
     XmlNode root = xmldoc.SelectSingleNode("root/profesori", null); 

      XmlNode prof = xmldoc.CreateNode(XmlNodeType.Element, "profesor", null); 

      XmlNode ime = xmldoc.CreateNode(XmlNodeType.Element, "ime", null); 
      ime.InnerText = name; 
      prof.AppendChild(ime); 

      XmlNode prezime = xmldoc.CreateNode(XmlNodeType.Element, "prezime", null); 
      prezime.InnerText = surname; 
      prof.AppendChild(prezime); 

      root.AppendChild(prof); 

      xmldoc.Save(Server.MapPath("data/sve.xml")); 

Ich habe auch versucht Namespace menager ihm hinzufügen:

XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable); 
       nsMgr.AddNamespace("ns", xmldoc.NamespaceURI); 
XmlNode root = xmldoc.SelectSingleNode("/ns:root/ns:profesori", nsMgr); 

und ich kann immer noch übergeordneten Knoten auswählen und neuen untergeordneten Knoten, um es hinzuzufügen. Im Debug-Modus ist das "root" -Objekt Null mit oder ohne Namespace, so dass ich am Ende natürlich eine Null-Zeiger-Ausnahme bekomme.

Was mache ich falsch?

P.S. Schemen, Namespaces XML-Datei sind alle lokalen und von mir writen, wenn das einen Unterschied macht ...

Antwort

9

Ihr erstes Problem ist, dass die Knotennamen in Ihrem XPath nicht mit denen des XML entsprechen. XML ist Groß- und Kleinschreibung, so müssen Sie Root verwenden, nicht root:

XmlNode root = xmldoc.SelectSingleNode("/ns:Root/ns:profesori", nsMgr); 

Als nächstes statt xmldoc.NamespaceURI, verwenden Sie den tatsächlichen NamespaceURI:

string strNamespace= "http://prpa.org/XMLSchema1.xsd"; 
nsMgr.AddNamespace("ns", strNamespace); 

oder dies tun:

string strNamespace= xmldoc.DocumentElement.NamespaceURI; 
nsMgr.AddNamespace("ns", strNamespace); 

Der NamespaceURI eines XmlDocument Objekts wird immer eine leere Zeichenfolge sein.

Und Sie sollten auch diesen Namensraum verwenden, wenn die Elemente zu erstellen:

XmlNode prof = xmldoc.CreateNode(XmlNodeType.Element, "profesor", strNamespace); 

XmlNode ime = xmldoc.CreateNode(XmlNodeType.Element, "ime", strNamespace); 
ime.InnerText = name; 
prof.AppendChild(ime); 

XmlNode prezime = xmldoc.CreateNode(XmlNodeType.Element, "prezime", strNamespace); 
prezime.InnerText = surname; 
prof.AppendChild(prezime); 

root.AppendChild(prof); 

könnten Sie auch prüfen, die CreateElement() Methode, die etwas kürzer sein würde:

XmlNode prof = xmldoc.CreateElement("profesor", strNamespace); 

Oder meine Präferenz wäre ein XmlWriter zu verwenden:

using(XmlWriter writer = root.CreateNavigator().AppendChild()) 
{ 
    writer.WriteStartElement("profesor", strNamespace); 
    writer.WriteElementString("ime", strNamespace, name); 
    writer.WriteElementString("prezime", strNamespace, surname); 
    writer.WriteEndElement(); 
} 
+0

ty für die Antwort, aber "root" Knoten bleibt Null l. Ich habe versucht, mit ganzen Namespace, und jetzt habe ich Ihre Lösung mit "string strNamespace = xmldoc.DocumentElement.NamespaceURI;", aber immer noch Null. – klo

+0

kranker spätester Zustand in der neuen Antwort – klo

+0

@klo ein anderes Problem ist, dass Sie "ns: root" anstelle von "ns: Wurzel" verwenden. XML und XPath unterscheiden zwischen Groß- und Kleinschreibung. – JLRishe