Как использовать XmlDocument и / или XDocument для анализа числовых ссылок на символы, закодированных в Windows 1252? - PullRequest
0 голосов
/ 10 июля 2009

Я работаю с данными XML из приложения, где мы получаем XML, как это:

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

Я хочу, чтобы значение атрибута и значения внутреннего текста были

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

но код такой:

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

или это:

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

дай мне:

{Swedish: ä ö Euro:  Quotes:    }

Они оба имеют правильную длину в 36, так что, очевидно, где я хочу получить евро и кавычки, я получаю что-то другое, предположительно, основанное на кодировке Unicode.

Ответы [ 2 ]

0 голосов
/ 10 июля 2009

Прежде всего, числовые символьные объекты интерпретируются одинаково независимо от того, какая кодировка входного файла. XML определяется строго с точки зрения Unicode (любая другая кодировка сначала отображается на Unicode), а числовые символьные объекты представляют кодовые точки Unicode.

Из-за этого ваш XML, если рассматривать как XML , имеет именно то семантическое значение, которое вы получили, используя XmlDocument, и никакие другие. Если вы хотите получить другой результат, то вы действительно пытаетесь проанализировать его как не совсем XML. Это не то, что не позволяет делать .NET XML API, даже XmlReader (потому что на самом деле это не то, что вы можете настраивать).

Самое близкое, к чему вы можете прийти - это предварительно обработать ввод «XML» как текст, заменив эти числовые символьные объекты на правильные кодовые точки Unicode - например, используя Regex. Однако это может быть непросто, поскольку для произвольного ввода XML потребуется, чтобы вы могли различать, где расширение не должно иметь место (например, внутри блоков CDATA).

0 голосов
/ 10 июля 2009

Пожалуйста, никогда не манипулируйте XML через тип String. Это очень часто испортит вещи.

Ваши тестовые примеры не используют файл реальных данных, не так ли? Не забудьте проверить, что вы собираетесь использовать. Вы не представляете, как тесты отличаются от реальности. Вам нужно взять один из файлов, которые вы будете обрабатывать, и использовать XDocument.Load, чтобы прочитать его.

После этого посмотрите на значения атрибутов, символ за символом.


Я попробовал следующее, и это сработало:

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

Вывод был:

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       ('?')

Я предполагаю, что вопросительные знаки связаны с тем, на что была установлена ​​моя консоль, но вы можете видеть, что числовые значения верны.

...