2009-07-09 13 views
0

ich mit XML-Daten aus einer Anwendung zu arbeiten, wo wir XML wie diese:Wie verwende ich XmlDocument und/oder XDocument, um in Windows 1252 codierte numerische Zeichenreferenzen zu analysieren?

<elt attrib="Swedish: &#228; &#246; Euro: &#128; Quotes: &#145; &#146; &#147; &#148;"> 
Swedish: &#228; &#246; Euro: &#128; Quotes: &#145; &#146; &#147; &#148; 
</elt> 

I der Attributwert und innere Textwerte

Swedish: ä ö Euro: € Quotes: ‘ ’ “ ” 

aber Code wie folgt sein soll:

Dim sXml As String = "<?xml version = ""1.0"" encoding = ""Windows-1252""?>" & vbCrLf & _ 
    "<elt attrib=""Swedish: &#228; &#246; Euro: &#128; Quotes: &#145; &#146; &#147; &#148;"">" & _ 
    "Swedish: &#228; &#246; Euro: &#128; Quotes: &#145; &#146; &#147; &#148;" & _ 
    "</elt>" 

Dim X As New XmlDocument 
X.LoadXml(sXml) 

TextBox1.Text = "Attribute: {" & X.DocumentElement.Attributes("attrib").Value & "}" & _ 
    vbCrLf & "InnerText: {" & X.DocumentElement.InnerText & "}" & vbCrLf & _ 
    "Length: " & Convert.ToString(Len(X.DocumentElement.InnerText)) 

oder dies:

Dim X As XDocument = XDocument.Parse(sXml) 

TextBox1.Text = "Attribute: {" & X.Root.Attribute("attrib").Value & "}" & _ 
    vbCrLf & "InnerText: {" & X.Root.Value & "}" & vbCrLf & _ 
    "Length: " & Convert.ToString(Len(X.Root.Value)) 

mir geben:

{Swedish: ä ö Euro: Quotes: } 

Sie haben sowohl die Länge auf 36 richtig ist, so offensichtlich, wo ich die Euro und Zitate wollen etwas anderes vermutlich auf einem Unicode-Codierung Ich bin immer bezogen.

Antwort

0

Zuerst werden numerische Zeichenentitäten unabhängig von der Codierung der Eingabedatei gleich interpretiert. XML wird ausschließlich in Unicode definiert (jede andere Codierung wird zuerst Unicode zugeordnet), und numerische Zeichenentitäten stellen Unicode-Codepunkte dar.

Aus diesem Grund hat Ihr XML, wenn es als XML behandelt wird, genau die semantische Bedeutung, die Sie mit XmlDocument und keine andere haben. Wenn Sie ein anderes Ergebnis erhalten möchten, versuchen Sie es wirklich als nicht-ganz-XML zu analysieren. Das ist etwas, was Ihnen keine .NET XML-API erlauben wird, nicht einmal XmlReader (weil es eigentlich nicht etwas sein soll, das Sie anpassen können).

Am nächsten kommt es, wenn Sie zunächst die Eingabe "XML" als Text vorverarbeiten und diese numerischen Zeichenentitäten durch korrekte Unicode-Codepunkte ersetzen, z. B. mit Regex. Dies kann jedoch schwierig sein, da es für beliebige XML-Eingaben erforderlich ist, dass Sie unterscheiden können, wo die Erweiterung nicht stattfinden soll (z. B. innerhalb von CDATA-Blöcken).

+0

Raten Sie, sie geben aus, was Sie "nicht ganz XML" nennen. In unserem Fall funktioniert Regex möglicherweise OK, weil es keine CDATA-Blöcke gibt. Irgendwelche anderen möglichen Krisenherde kommen in den Sinn von CDATA?Danke für die Erklärung und den Vorschlag. –

+0

Technisch gesehen werden Charakter- und Entity-Referenzen in Kommentaren und PIs nicht erweitert, aber ich bin mir ziemlich sicher, dass dir das erstere egal sein wird und dass es sehr unwahrscheinlich ist, dass du dich für letzteres interessierst. –

+0

Richtig, in den Daten, die wir bekommen, kommen weder Kommentare noch PIs vor. Danke, das ist sehr hilfreich. –

0

Bitte manipulieren Sie XML niemals über den String-Typ. Es wird sehr oft Dinge vermasseln.

Ihre Testbeispiele verwenden nicht die echte Datendatei, oder? Stellen Sie sicher, dass Sie testen, was Sie verwenden werden. Sie haben keine Ahnung, wie sich die Tests von der Realität unterscheiden. Sie müssen eine der Dateien verarbeiten, die Sie verarbeiten, und XDocument.Load verwenden, um sie einzulesen.

Danach sehen Sie sich die Attributwerte an, Zeichen für Zeichen.


ich folgendes versucht, und es hat funktioniert:

using (var reader = XmlReader.Create(@"..\..\..\..\Swedish.xml")) 
{ 
    var sw = XDocument.Load(reader); 
    var element = sw.Element("elt"); 
    if (element != null) 
    { 
     var attribute = element.Attribute("attrib"); 
     if (attribute != null) 
     { 
      var v = attribute.Value; 
      for (var i=0; i<36; i++) 
      { 
       var c = v[i]; 

       Console.WriteLine("v[{0}]={1} \t('{2}')", i,(int) c, c); 
      } 

      Console.WriteLine(); 
     } 
    } 
} 

Der Ausgang war:

v[0]=83   ('S') 
v[1]=119  ('w') 
v[2]=101  ('e') 
v[3]=100  ('d') 
v[4]=105  ('i') 
v[5]=115  ('s') 
v[6]=104  ('h') 
v[7]=58   (':') 
v[8]=32   (' ') 
v[9]=228  ('ä') 
v[10]=32  (' ') 
v[11]=246  ('ö') 
v[12]=32  (' ') 
v[13]=69  ('E') 
v[14]=117  ('u') 
v[15]=114  ('r') 
v[16]=111  ('o') 
v[17]=58  (':') 
v[18]=32  (' ') 
v[19]=128  ('?') 
v[20]=32  (' ') 
v[21]=81  ('Q') 
v[22]=117  ('u') 
v[23]=111  ('o') 
v[24]=116  ('t') 
v[25]=101  ('e') 
v[26]=115  ('s') 
v[27]=58  (':') 
v[28]=32  (' ') 
v[29]=145  ('?') 
v[30]=32  (' ') 
v[31]=146  ('?') 
v[32]=32  (' ') 
v[33]=147  ('?') 
v[34]=32  (' ') 
v[35]=148  ('?') 

ich die Fragezeichen sind auf Grund davon ausgehen, was auch immer meine Konsole gesetzt wurde, aber Sie können sehen, dass die numerischen Werte korrekt sind.

Verwandte Themen