2013-02-10 8 views
5

Sto cercando di aggiungere nuovi nodi a un file XML esistente. ho questo file con gli elementi prima prova in esso:C#, XML, aggiunta di nuovi nodi

<?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> 

Ho usato questo schema per generare questo documento XML

<?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> 

Ora, ho bisogno di aggiungere nuovo nodo

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

Ho provato fino ad ora:

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")); 

Ho anche provato ad aggiungere namespace Menager ad esso:

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

ed ancora non posso selezionare nodo padre e aggiungere nuovi nodo figlio ad esso. In modalità debug, l'oggetto "root" è nullo con o senza spazio dei nomi, quindi alla fine I off ottiene un'eccezione di puntatore nullo.

Cosa sto sbagliando?

P.S. Schemi, namespace, file xml sono tutti locali e scritti da me, se questo fa alcuna differenza ...

risposta

9

Il tuo primo problema è che i nomi dei nodi nel tuo XPath non corrispondono a quelli dell'XML. XML è case sensitive, quindi è necessario utilizzare Root, non root:

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

Avanti, invece di xmldoc.NamespaceURI, usa il reale uri namespace:

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

o fanno questo:

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

Il NamespaceURI di un oggetto XmlDocument sarà sempre una stringa vuota.

E si dovrebbe anche usare questo spazio dei nomi quando si creano gli elementi:

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); 

Si potrebbe anche considerare utilizzando il metodo CreateElement(), che sarebbe un po 'più corta:

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

Oppure, la mia preferenza sarebbe essere utilizzare XmlWriter:

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

ty per la risposta, ma il nodo "root" rimane nul l. Ho provato con tutto lo spazio dei nomi e ora ho implementato la tua soluzione con "string strNamespace = xmldoc.DocumentElement.NamespaceURI;", ma ancora nullo. – klo

+0

post malato ultimo stato nella nuova risposta – klo

+0

@klo Un altro problema è che stai usando "ns: root" invece di "ns: Root". XML e XPath sono case sensitive. – JLRishe