Как получить неэкранированную длину внутреннего текста XElement?
Я пытаюсь проанализировать следующий файл ресурсов Java - который является XML. Я занимаюсь синтаксическим анализом с использованием инструментов C# и XDocument, поэтому здесь не вопрос Java.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="problem"> test </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 = ' test ', 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
У вас есть две разные строки, и  
есть, но в формате Юникод. Один из возможных способов вернуть вещи - это вручную заменить неразрывный пробел на " "
String result = one.Replace(((char) 160).ToString(), " ");
Благодаря Дмитрию, следуя его предложению, я сделал функцию, которая заставляет вещи работать для списка кодов 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();
}