Ошибка разбора XElement при попытке разбора строки - PullRequest
0 голосов
/ 20 сентября 2018

Я получаю ошибку синтаксического анализа xml при попытке анализа строки (с CDATA в CDATA)

var cont = "<op><![CDATA[someData<p><![CDATA[someotherData]]></p></op>";
XElement.Parse(cont);

Ошибка:

The 'op' start tag on line 1 position 2 does not match the end tag of 'p'. Line 1, position 52.

Можем ли мы иметь CDATA в CDATA?Если мы можем, тогда почему я получаю ошибку.

Ниже код работает нормально (он не содержит CDATA в CDATA).

var cont = "<op><![CDATA[someData]]</op>";
XElement.Parse(cont);

1 Ответ

0 голосов
/ 21 сентября 2018
1  <op>
2      <![CDATA[
3          someData
4          <p>
5              <![CDATA[someotherData]]>
6          </p>
7  </op>

Когда синтаксический анализатор XML встречает ]]> в строке 5, он завершает первый <![CDATA[, встреченный в строке 2.В результате, вы никогда не можете вложить CDATA в CDATA.

CDATA не предназначен для хранения элементов xml, но для хранения символьных данных, которые могут содержать такие символы, как <, > и т. Д., Что позволяет нам избегать экранирования их как &lt;, &gt; соответственно и написать их и отобразить их в чистом виде.

Таким образом, содержимое между <![CDATA[ и ]] будет обрабатываться как обычный текст без дальнейшей обработки, даже если похоже, что существует иерархия ,Другими словами, это простые строки .Давайте возьмем ваш код в качестве примера:

var cont = "<op><![CDATA[ <foo><bar></bar></foo> ]]></op>";
var xml=XElement.Parse(cont);

Здесь FirstNode из xml будет простым текстом foo><bar></bar></foo>, а FirstNode из FirstNode будет null,

Поскольку синтаксический анализатор всегда будет обрабатывать данные между <![CDATA[ и ]] как простую строку, «стандартного», наиболее близкого к правильному способу их представления.Просто закодируйте их и расшифруйте их.Например, мы можем urlencode данных:

string xmlstr= @"<op><![CDATA[
    <helloworld/>
    someData%0A%3Cp%3E%0A%3C!%5BCDATA%5BsomeotherData%5D%5D%3E%0A%3C%2Fp%3E
]]></op>";
var xml = XElement.Parse(xmlstr);

var subxmlString=System.Web.HttpUtility.UrlDecode(xml.Value);
// make sure there' must be a root element
var subxml= XElement.Parse($"<root>${subxmlString}</root>");  
...