2009-11-24 19 views
16

Sto lavorando contro un xml api di terze parti. Hanno definito una struttura XML richiesta simile alla seguente.Nome elemento xml con i due punti

<ns1:E xmlns:ns1="schema"> 
<ns1:B> 
    <ns2:S> 
     <ns2:V> 
      <ns2:Bl /> 
     </ns2:V> 
    </ns2:S> 
</ns1:B> 
</ns1:E> 

C'è una tabella SQL con le informazioni che ho bisogno di mettere in questo formato xml. Ho un adattatore LINQ to SQL per ottenere i dati e sto usando un System.Xml per creare un documento XML.

XmlDocument.CreateElement("ns1:E"); etc 

Questo funziona benissimo fintanto che rimuovo i due punti dai nomi degli elementi. Con i due punti, solo il lato destro dei due punti si trova nel nome dell'elemento. So che i due punti sono un no-no ma non ho alcun controllo su ciò che l'API di terze parti sta dettando.

Quali sono le mie opzioni per aggirare questo? Esistono modi utili per forzare i due punti nei nomi degli elementi? Non devo usare XMLDocument ma non sono sicuro di quale altro metodo mi porterà lì.

AGGIORNAMENTO: Mi rendo conto che lo <ns1: fa riferimento a uno spazio dei nomi. E sì, ci sono 2. Quando si scrive il XML, posso farlo funzionare se dico -

XmlDocument.CreateElement(ns1:E", "http://schema); 

Tuttavia, l'output XML di questo è

<ns1:E xmlns:ns1="http://schema"> 

Se dico solo XmlDocument.CreateElement("ns1:E"); con no uri, quindi l'output è solo <E>. Non voglio che l'output abbia il riferimento allo schema ma ho bisogno di avere il prefisso. Il risultato che voglio ottenere è semplicemente <ns1:E>. Entrambi i namspace sono dichiarati in alto, il che direi che avrei dovuto dichiararli su ogni nodo.

risposta

0

La parola prima dei due punti è lo spazio dei nomi. Se si desidera avere un elemento "ns1: E", è necessario creare un elemento denominato "E" e impostare il suo spazio dei nomi su "ns1".

+0

Grazie, ha senso, ma in qualche modo non sto ottenendo il risultato che sto cercando ancora. Non so perché. Se si specifica un riferimento uri o ns, il nome dell'elemento è corretto ma aggiunge il riferimento all'output che non desidero. Se non lo faccio, il prefisso non viene aggiunto. – nelsonwebs

5

I due punti indicano che tali elementi si trovano in ns1 namespace. Questo è necessario quando si utilizzano più schemi. Supponendo che il documento utilizzi solo ns1, è essenzialmente equivalente a non avere alcun "ns1:" in quei tag. Vedi this guide per maggiori informazioni.

+3

In realtà, questi due punti indicano che gli elementi si trovano nello spazio dei nomi 'schema'. 'ns1' non è lo spazio dei nomi; è l'abbreviazione dello spazio dei nomi. Può cambiare; il nome del namespace non può - non senza diventare un namespace diverso. –

5

Il documento XML che hai postato non è in realtà ben formato, perché il ns2 sigla assegnata a molti degli elementi non è associato a uno spazio dei nomi.Fisso, potrebbe apparire come questo:

<ns1:E xmlns:ns1="schema" xmlns:ns2="my-namespace"> 
    <ns1:B> 
    <ns2:S> 
     <ns2:V> 
     <ns2:Bl /> 
     </ns2:V> 
    </ns2:S> 
    </ns1:B> 
</ns1:E> 

Il documento XML di cui sopra è semanticamente equivalente a questo:

<s:E xmlns:s="schema"> 
    <s:B> 
    <S xmlns="my-namespace"> 
     <m:V xmlns:m="my-namespace"> 
     <s:Bl xmlns:s="my-namespace"/> 
     </m:V> 
    </S> 
    </s:B> 
</s:E> 

E a questo:

<E xmlns="schema"> 
    <B xmlns="schema"> 
    <S xmlns="my-namespace"> 
     <V> 
     <Bl/> 
     </V> 
    </S> 
    </B> 
</E> 

In tutti e tre i casi, gli elementi E e B sono nello spazio nomi schema, mentre gli elementi S, V e Bl ar e nello spazio dei nomi my-namespace.

I prefissi dei nomi di spazio sono utili, ma in senso stretto non sono necessari. È possibile creare documenti XML, come l'ultimo esempio, che non usano prefissi e che dichiarano esplicitamente lo spazio dei nomi per ogni elemento.

Se, nell'elaborazione dell'XML, pensi di avere a cuore il prefisso utilizzato da un determinato elemento, quasi sicuramente ti sbagli. L'unica cosa a cui tieni è il namespace a cui appartiene. Per esempio, se carico qualsiasi di questi tre documenti in un XmlDocument, il seguente codice scriverà l'elemento 'Bl':

XmlNamespaceManager ns = new XmlNamespaceManager(d.NameTable); 
    ns.AddNamespace("a", "schema"); 
    ns.AddNamespace("b", "my-namespace"); 
    Console.Write(d.SelectSingleNode("/a:E/a:B/b:S/b:V/b:Bl", ns).OuterXml); 

Quando si dice:

non lo faccio voglio che l'output abbia il riferimento allo schema ma ho bisogno di avere il prefisso. Il risultato che voglio ottenere è semplicemente <ns1:E>.

siete quasi certamente in errore. Un elemento il cui tag è ns1:E non ha senso a meno che il prefisso ns1 non sia associato a uno spazio dei nomi, né in quell'elemento né in uno dei suoi antenati. (Inoltre, uno spazio dei nomi non è un riferimento schema.) Se si utilizza

CreateElement("ns1", "E", "schema"); 

per creare l'elemento, e quindi aggiungere a un elemento che ha già dichiarato ns1 come il prefisso per il schema spazio dei nomi, poi il Il DOM aggiungerà l'elemento senza la dichiarazione dello spazio dei nomi, perché in quel contesto non è necessario. Se ns1 non viene dichiarato (o viene dichiarato abbreviato in uno spazio dei nomi diverso da schema), il DOM attaccherà una dichiarazione dello spazio dei nomi sull'elemento e sul prefisso.

tl; dr: Ti interessano gli spazi dei nomi, non i prefissi dei namespace.

1

(So che è una vecchia domanda, ma sto facendo qualcosa di equivalente e ho capito come agitare il pollo morto per farlo funzionare. Sto documentandolo in modo che possa trovarlo più tardi.)

string myName = "foo"; 

string ns_local = root.GetNamespaceOfPrefix("local"); 
string ns_x = root.GetNamespaceOfPrefix("x"); 

System.Xml.XmlNode newNode = doc.CreateNode(System.Xml.XmlNodeType.Element, "local", "MyTag", ns_local); 

System.Xml.XmlNode attr = doc.CreateNode(System.Xml.XmlNodeType.Attribute, "Key", ns_x); 
attr.Value = myName; 
newNode.Attributes.SetNamedItem(attr); 

attr = doc.CreateNode(System.Xml.XmlNodeType.Attribute, "MyAttr", ""); 
attr.Value = myName; 
newNode.Attributes.SetNamedItem(attr); 

nodeToAppendTo.AppendChild(newNode); 

Questo mi dà un tag che assomiglia

<local:MyTag x:Key="foo" MyAttr="foo" /> 
2
<ns1:E xmlns:ns1="schema"> 
    <ns1:B> 
     <ns2:S> 
     <ns2:V> 
      <ns2:Bl /> 
     </ns2:V> 
     </ns2:S> 
    </ns1:B> 
</ns1:E> 

Quindi, per ottenere il risultato di cui sopra utilizzando Crea XmlElement potrebbe essere raggiunto, come di seguito:

CreateElement("ns1","E", "schema"); 
CreateElement("ns1","B", "schema"); 
CreateElement("ns2","S", "schema"); 
CreateElement("ns2","V", "schema"); 
CreateElement("ns2","B1", "schema"); 

Qui l'elemento "E" è l'elemento radice quindi lo prefigura con "ns1" insieme allo schema.

Poiché tutti gli altri elementi menzionati come "B", "S", "V", "B1" sono elementi figlio "E" è prefissi con il prefisso menzionato ma non do visualizza nuovamente lo schema per la Elementi del bambino.

E quindi si ottiene l'output desiderato come sopra con schema nell'elemento radice e solo prefisso per elementi figlio.

Problemi correlati