Квадратные скобки XmlReader приводят к тому, что читатель переходит в состояние с ошибкой - PullRequest
1 голос
/ 02 ноября 2009

У меня есть XmlReader, который пытается прочитать текст в списке элементов. У меня проблемы с получением текста для читателя: "a [z]". Если я попытаюсь с текстом "a [z]" (то же самое, но с двумя конечными пробелами), он работает нормально. Ниже приведен пример:

TextReader tr = new StringReader("a [ z ]");
XmlReaderSettings settings = new XmlReaderSettings
{
    ConformanceLevel = ConformanceLevel.Fragment,
    ProhibitDtd = false,
    ValidationType = ValidationType.None,
    XmlResolver = null,
    CheckCharacters = false,
    IgnoreProcessingInstructions = true,
};
XmlReader reader = XmlReader.Create(tr, settings);
reader.Read();

StringBuilder sb = new StringBuilder();

while (!reader.EOF)
{
    if (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.Whitespace)
    {
        sb.Append(reader.Value);
        reader.Read();
    }   
}

// sb.ToString() should be "a [ z ]"

При запуске происходит сбой с сообщением: «System.Xml.XmlException: неожиданный конец файла. Строка 1, позиция 7.» и трассировка стека:

at System.Xml.XmlTextReaderImpl.Throw(Exception e) 
at System.Xml.XmlTextReaderImpl.ParseText(Int32& startPos, Int32& endPos, Int32& outOrChars)
at System.Xml.XmlTextReaderImpl.FinishPartialValue()
at System.Xml.XmlTextReaderImpl.get_Value()
at LocalisationFormats.Tests.Shared.InlineElements.InlineElementHelperTest.Test()

Когда вы пытаетесь его отладить, Reader находится в состоянии ReadState «Error», а Reader.Value равно «a [z», а затем вы отключаете ридер и получаете OutOfMemoryExecption.

Кто-нибудь есть предложения?

РЕДАКТИРОВАТЬ: убрано лишнее, если блок из фрагмента кода при предложении от Грегуара.

Ответы [ 3 ]

2 голосов
/ 02 ноября 2009

Я считаю, что проблема заключается в том, что при загрузке строки, не отформатированной в XML, в объект XmlReader.

«XmlReader обеспечивает прямой доступ только для чтения к потоку данных XML. Класс XmlReader соответствует расширяемому языку разметки W3C (XML) 1.0 и пространствам имен в рекомендациях XML». & "XmlReader создает исключение XmlException при ошибках синтаксического анализа XML." - Статья класса MSDN XmlReader http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx

Попробуйте вместо этого загрузить и прочитать фактические данные XML, изменив:

TextReader tr = new StringReader("a [ z ]");

до:

TextReader tr = new StringReader("<node>a [ z ]</node>");

или поочередно, если вам нужна каждая фигура в своем собственном узле:

TextReader tr = new StringReader("<node>a</node><node> </node><node>[</node><node> </node><node>z</node><node> </node><node>]</node>");

Я предоставляю полный источник для последнего примера, потому что я ДУМАЮ, что это то, к чему вы стремитесь здесь.

TextReader tr = new StringReader("<node>a</node><node> </node><node>[</node><node> </node><node>z</node><node> </node><node>]</node>");
XmlReaderSettings settings = new XmlReaderSettings
{
    ConformanceLevel = ConformanceLevel.Fragment,
    ProhibitDtd = false,
    ValidationType = ValidationType.None,
    XmlResolver = null,
    CheckCharacters = false,
    IgnoreProcessingInstructions = true,
};
XmlReader reader = XmlReader.Create(tr, settings);
reader.Read();

StringBuilder sb = new StringBuilder();

while (!reader.EOF)
{
    string s = reader.ReadElementString();

    if (s != " ")
    {
        sb.Append(s);
    }
}

Это позволит вам перебирать узлы, получая полные строковые значения без исключений.

~ md5sum ~

0 голосов
/ 18 июля 2012

Извините, что вытащил трехлетнюю проблему, но у меня была такая же проблема. Любой гугл из будущего:

Похоже, что OP поднял это с парнями из Microsoft - connect.microsoft.com / VisualStudio / feedback :

Спасибо за сообщение об этой проблеме. Мы исправили это в .NET 4.0. Мы не планируем исправлять это в предыдущих версиях .NET. Обновление до .NET 4.0 решит эту проблему.

Спасибо, Арун Чандрасекхар, Старший менеджер программы, Команда XML

Для тех из нас, кто все еще придерживается .Net <4.0 (в моем случае 2.0), я обошел это с этим ужасным хаком: </p>

const string openSquareBracketReplacement = "##OSB##";
const string closeSquareBracketReplacement = "##CSB##";

xml = xml
    .Replace("[", openSquareBracketReplacement)
    .Replace("]", closeSquareBracketReplacement);

// Build an XmlReader and use it.

return xml
    .Replace(openSquareBracketReplacement, "[")
    .Replace(closeSquareBracketReplacement, "]");

Очевидно, что это полностью нарушит обработку CDATA, но для моих целей это нормально.

0 голосов
/ 16 июня 2010

Я проверил, и это было исправлено в .Net 4, но все еще не работает в .Net 3.5 на момент публикации.

...