XML-парсер, несколько корней - PullRequest
2 голосов
/ 26 августа 2011

Это часть входной строки, я не могу ее изменить, она всегда будет поступать таким образом (через разделяемую память), но я могу изменить после того, как я поместил ее в строку, конечно:

<sys><id>SCPUCLK</id><label>CPU Clock</label><value>2930</value></sys><sys><id>SCPUMUL</id><label>CPU Multiplier</label><value>11.0</value></sys><sys><id>SCPUFSB</id><label>CPU FSB</label><value>266</value></sys>

Я прочитал это с обоими:

        String.Concat(
            XElement.Parse(encoding.GetString(bytes))
                .Descendants("value")
                .Select(v => v.Value));

и

    XmlDocument document = new XmlDocument();
    document.LoadXml(encoding.GetString(bytes));
    XmlNode node = document.DocumentElement.SelectSingleNode("//value");
    Console.WriteLine("node = " + node);

но они оба имеют ошибку при запуске; что вход имеет несколько корней (Есть несколько корневых элементов кавычки), я не хочу разбивать строку.

Есть ли какой-нибудь способ прочитать строку, принимающую значение между <value> и </value>, не разбивая строку на несколько входов?

Ответы [ 3 ]

5 голосов
/ 26 августа 2011

Это не правильно сформированный документ XML, поэтому большинство инструментов XML не смогут его обработать.

Исключением является XmlReader. Посмотрите XmlReaderSettings.ConformanceLevel в MSDN. Если вы установите ConformanceLevel.Fragment, вы можете создать XmlReader с этими настройками и использовать его для чтения элементов из потока, который не имеет элемента верхнего уровня.

Вы должны написать код, который использует XmlReader.Read(), чтобы сделать это - вы не можете просто передать его в XmlDocument (который требует наличия одного элемента верхнего уровня).

например.,

var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (var reader = XmlReader.Create(stream, readerSettings))
{
    while (reader.Read())
    {
        using (var fragmentReader = reader.ReadSubtree())
        {
            if (fragmentReader.Read())
            {
                var fragment = XNode.ReadFrom(fragmentReader) as XElement;

                // do something with fragment
            }
        }
    }
}
2 голосов
/ 26 августа 2011

XML-элементы должны иметь ОДИН корневой элемент с любой дочерней структурой, которую вы хотите. Ваша строка XML выглядит так:

<sys>
   ...
</sys>
<sys>
   ...
</sys>

Допустимая версия будет:

<someRootElement>
  <sys>
   ...
  </sys>
  <sys>
   ...
  </sys>
</someElement>

Попробуйте:

XmlDocument document = new XmlDocument();
document.LoadXml("<root>"+encoding.GetString(bytes)+"</root>");
XmlNode node = document.DocumentElement.SelectSingleNode("//value");
Console.WriteLine("node = " + node);
0 голосов
/ 26 ноября 2015

Это решение успешно анализирует все типы узлов, включая текстовые узлы:

var settings = new XmlReaderSettings{ConformanceLevel = ConformanceLevel.Fragment};
var reader = XmlReader.Create(stream, settings);
while(reader.Read())
{
    while(reader.NodeType != XmlNodeType.None)
    {
        if(reader.NodeType == XmlNodeType.XmlDeclaration)
        {
            reader.Skip();
            continue;
        }
        XNode node = XNode.ReadFrom(reader);
    }
}

Пропускает декларацию XML, поскольку она не является узлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...