2012-07-13 16 views
6

Secondo questa domanda:LINQ to XML ignora le interruzioni di riga in attributi

Are line breaks in XML attribute values allowed?

interruzioni di riga negli attributi XML sono perfettamente validi (anche se forse non consigliata):

<xmltag1> 
    <xmltag2 attrib="line 1 
line 2 
line 3"> 
    </xmltag2> 
</xmltag1> 

Quando sono parse tale XML che utilizza LINQ in XML (System.Xml.Linq), tali interruzioni di riga vengono convertite automaticamente nello spazio ' ' caratteri.

C'è un modo per dire al parser XDocument.Load() di conservare quelle interruzioni di riga?

P.S .: L'XML che sto analizzando è scritto da software di terze parti, quindi non posso modificare il modo in cui vengono scritte le interruzioni di riga.

+0

Se si stanno scrivendo gli attributi in modo programmatico, guardare questo articolo che mostra diversi modi di sfuggire alla stringa.http: //weblogs.sqlteam.com/mladenp/archive/2008/10/21/Different-ways-how-to-escape- an-XML-string-in-C.aspx ricorda che non devono essere sfuggiti solo i linebreak. –

risposta

9

Se si desidera conservare le interruzioni di riga nei valori degli attributi, è necessario scriverli con i riferimenti di carattere, ad es.

<foo bar="Line 1.&#10;Line 2.&#10;Line3."/> 

come altri saggi il parser XML li normalizzare agli spazi, in base alla specifica XML http://www.w3.org/TR/xml/#AVNormalize.

[modifica] Se si vuole evitare la normalizzazione valore dell'attributo poi caricare il XML con un lascito XmlTextReader aiuta:

  string testXml = @"<foo bar=""Line 1. 
Line 2. 
Line 3.""/>"; 

      XDocument test; 
      using (XmlTextReader xtr = new XmlTextReader(new StringReader(testXml))) 
      { 
       xtr.Normalization = false; 
       test = XDocument.Load(xtr); 
      } 
      Console.WriteLine("|{0}|", test.Root.Attribute("bar").Value); 

che emette

|Line 1. 
Line 2. 
Line 3.| 
+0

Grazie, ma come ho scritto nella mia domanda, l'XML è scritto da un software di terze parti, quindi non posso cambiarlo. Forse ho bisogno di un qualche tipo di sostituzione RegEx che converta le interruzioni di linea a – cheeesus

+0

Ho visto quella nota nella tua domanda, ma in questo caso c'è una specifica chiara e il risultato che ottieni è conforme alle specifiche. Così ho scritto quella risposta per far notare che il comportamento che ottieni è quello giusto, anche se non è voluto nel tuo caso. Penso che un 'XmlTextReader' legacy consentirà comunque di evitare la normalizzazione del valore degli attributi, quindi modificherai la mia risposta per dimostrarlo. –

+0

grazie! il 'XmlTextReader' fa il lavoro – cheeesus

0

le interruzioni di riga non sono spazi quando analizzati (non codice ASCII 32) se passi attraverso ogni lettera vedrai che lo "spazio" "è un codice ASCII 10 = LF (LineFeed) (!!) - quindi i linebreak sono ancora presenti se hai bisogno di provare a sostituire loro con un ASCII 13 nel tuo codice ... (caselle di testo (finestre forme) non mostrano LF come un'interruzione di riga)

+0

Grazie, l'ho provato prima, e ho davvero due codici ASCII di 32 caratteri dove dovrebbero essere le interruzioni di riga. Lo proverò di nuovo per essere sicuro. – cheeesus

+1

L'ho provato di nuovo. Entrambi i caratteri ''\ r'' e'' \ n'' nell'attributo XML vengono convertiti in spazi '' '' (codice ASCII 32). – cheeesus

+0

diritto - che si applica a una sezione cdata - non è stato possibile trovare un modo per conservare le interruzioni di riga al momento. è un posto di 32 32 a LB un'opzione per voi? – Cadburry

0

Secondo MSDN:

Sebbene processori XML conservano tutti gli spazi bianchi nel contenuto dell'elemento, spesso normalizzare in valori di attributo. Tabulazioni, ritorni a capo e spazi sono riportati come spazi singoli. In alcuni tipi di attributi, riducono lo spazio bianco che precede o segue il corpo principale del valore e riducono lo spazio bianco all'interno del valore in spazi singoli. (Se un DTD è disponibile, questo taglio sarà eseguito su tutti gli attributi che non sono di tipo CDATA.)

Ad esempio, un documento XML potrebbe contenere i seguenti:

rapporti parser
<whiteSpaceLoss note1="this is a note." note2="this 
is 
a 
note."> 

un XML sia attributo valori come "this is a note.", conversione delle interruzioni di riga in spazi singoli.

Non riesco a trovare nulla su come preservare gli spazi bianchi degli attributi, ma suppongo che potrebbe essere impossibile secondo questa spiegazione.