Как получить неэкранированную длину внутреннего текста XElement?

Я пытаюсь проанализировать следующий файл ресурсов Java - который является XML. Я занимаюсь синтаксическим анализом с использованием инструментов C# и XDocument, поэтому здесь не вопрос Java.

<?xml version="1.0" encoding="utf-8"?>
  <resources>
    <string name="problem">&#160;test&#160;</string>
    <string name="no_problem"> test </string>
  </resources>

Проблема в том, что метод XDocument.Load (string path) загружает его как XDocument с двумя одинаковыми элементами XElements.

Я загружаю файл.

string filePath = @"c:\res.xml"; // whatever
var xDocument = XDocument.Load(filePath);

Когда я анализирую объект XDocument, здесь возникает проблема.

foreach (var node in xDocument.Root.Nodes())
{
    if (node.NodeType == XmlNodeType.Element)
    {
        var xElement = node as XElement;
        if (xElement != null) // just to be sure
        {
            var elementText = xElement.Value;
            Console.WriteLine("Text = '{0}', Length = {1}", 
                elementText, elementText.Length);
        }
    }
}

Это производит следующие 2 строки:

"Text = ' test ', Length = 6" 
"Text = ' test ', Length = 6"

Я хочу получить следующие 2 строки:

"Text = ' test ', Length = 6"
"Text = '&#160;test&#160;', Length = 16"

Кодировка документа - UTF8, если это как-то актуально.

2 ответа

Решение
string filePath = @"c:\res.xml"; // whatever
var xDocument = XDocument.Load(filePath);
String one = (xDocument.Root.Nodes().ElementAt(0) as XElement).Value;//< test >
String two = (xDocument.Root.Nodes().ElementAt(1) as XElement).Value;//< test >
Console.WriteLine(one == two); //false  
Console.WriteLine(String.Format("{0} {1}", (int)one[0], (int)two[0]));//160 32

У вас есть две разные строки, и &#160; есть, но в формате Юникод. Один из возможных способов вернуть вещи - это вручную заменить неразрывный пробел на "&#160;"

String result = one.Replace(((char) 160).ToString(), "&#160;");

Благодаря Дмитрию, следуя его предложению, я сделал функцию, которая заставляет вещи работать для списка кодов Unicode.

    private static readonly List<int> UnicodeCharCodesReplace = 
       new List<int>() { 160 }; // put integers here

    public static string UnicodeUnescape(this string input)
    {
        var chars = input.ToCharArray();

        var sb = new StringBuilder();

        foreach (var c in chars)
        {
            if (UnicodeCharCodesReplace.Contains(c))
            {
                // Append &#code; instead of character
                sb.Append("&#");
                sb.Append(((int) c).ToString());
                sb.Append(";");
            }
            else
            {
                // Append character itself
                sb.Append(c);
            }
        }

        return sb.ToString();
    }
Другие вопросы по тегам