Подтвердить что ты не робот

Возможно ли иметь HTML-текст или CDATA внутри атрибута XML?

Я продолжаю получать "Ошибка парсера XML: Unterminated attribute" с моим парсером, когда я пытаюсь помещать текст HTML или CDATA внутри моего XML-атрибута. Есть ли способ сделать это или это запрещено стандартом?

4b9b3361

Ответ 1

Если атрибут не является токенированным или перечисляемым типом, он обрабатывается как CDATA. Подробные сведения о том, как обрабатывается атрибут, можно найти в Extensible Markup Language (XML) 1.0 (пятое издание).

3.3.1 Типы атрибутов

Типы атрибутов XML имеют три типа: тип строки, набор токенированных типов и перечисляемые типы. Тип строки может принимать любую литеральную строку в качестве значения; токенизированные типы более ограничены. Ограничения на допустимость, отмеченные в грамматике, применяются после того, как значение атрибута было нормализовано, как описано в 3.3.3. Нормализация значения атрибута.

[54]  AttType       ::=    StringType | TokenizedType | EnumeratedType
[55]  StringType    ::=    'CDATA'
[56]  TokenizedType ::=    'ID' [VC: ID]
            [VC: One ID per Element Type]
            [VC: ID Attribute Default]
        | 'IDREF'      [VC: IDREF]
        | 'IDREFS'     [VC: IDREF]
        | 'ENTITY'     [VC: Entity Name]
        | 'ENTITIES'   [VC: Entity Name]
        | 'NMTOKEN'    [VC: Name Token]
        | 'NMTOKENS'   [VC: Name Token]

...

3.3.3 Нормализация атрибута

Прежде чем значение атрибута будет передано в приложение или проверено на достоверность, процессор XML ДОЛЖЕН нормализовать значение атрибута, применяя приведенный ниже алгоритм или используя какой-либо другой метод, так что значение, переданное приложению, будет одинаковым как это было сделано с помощью алгоритма.

  • Все разрывы строк ДОЛЖНЫ быть нормализованы при вводе на #xA, как описано в 2.11 Обработка конца строки, так что остальная часть этого алгоритм работает с текстом, нормализованным таким образом.
  • Начните с нормализованного значения, состоящего из пустой строки.
  • Для каждого символа, ссылки на объект или ссылки на символ в ненормализованном значении атрибута, начиная с первого и продолжающегося до последнего, выполните следующие действия:
    • Для ссылки на символ добавьте ссылочный символ к нормализованному значению.
    • Для ссылки на сущность рекурсивно применяйте шаг 3 этого алгоритма к заменяющему тексту объекта.
    • Для символа пробела (# x20, #xD, #xA, # x9) добавьте пробельный символ (# x20) к нормализованному значению.
    • Для другого символа добавьте символ к нормализованному значению.

Если тип атрибута не является CDATA, то XML-процессор ДОЛЖЕН продолжить обработку нормализованного значения атрибута, отбрасывая символы ведущего и конечного пробелов (# x20) и заменяя символы пробела (# x20) на одно пространство (# x20).

Обратите внимание, что если значение ненормализованного атрибута содержит ссылку на символ пробела, отличную от пробела (# x20), нормализованное значение содержит сам ссылочный символ (#xD, #xA или # x9). Это контрастирует с случаем, когда ненормализованное значение содержит символ пробела (а не ссылку), который заменяется символом пробела (# x20) в нормализованном значении, а также контрастирует с случаем, когда ненормализованное значение содержит ссылку на сущность, текст замены содержит символ пробела; рекурсивная обработка, символ пробела заменяется символом пробела (# x20) в нормализованном значении.

Все атрибуты, для которых не было прочитано объявление, ДОЛЖНЫ обрабатываться не проверяющим процессором, как будто объявлено CDATA.

Это ошибка, если значение атрибута содержит ссылку для объекта, для которого не было прочитано декларация.

Ответ 2

Нет, CDATA не может быть значением атрибута. Он может быть только внутри элемента.

Ответ 3

Атрибуты могут иметь только обычный текст внутри, без тегов, комментариев или других структурированных данных. Вам нужно избегать любых специальных символов, используя объекты символов. Например:

<code text="&lt;a href=&quot;/&quot;&gt;">

Это даст атрибуту text значение <a href="/">. Обратите внимание, что это простой текст, поэтому, если вы хотите рассматривать его как HTML, вам придется запускать эту строку через парсер HTML самостоятельно. XML DOM не будет анализировать атрибут text для вас.

Ответ 4

CDATA, к сожалению, двусмысленно сказать здесь. Есть разделы CDATA и " CDATA Тип атрибута ".

Значение вашего атрибута может иметь тип CDATA с типом атрибута CDATA.

Вот xml, который содержит раздел "CDATA" ( ака. CDSect):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<elemke>
<![CDATA[
foo
]]>
</elemke>

Вот xml, который содержит "Тип атрибута CDATA" (как AttType):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE elemke [
<!ATTLIST brush wood CDATA #REQUIRED>
]>

<elemke>
<brush wood="guy&#xA;threep"/>
</elemke>

Вы не можете использовать "Раздел CDATA" для значения атрибута: неверно: <brush wood=<![CDATA[foo]]>/>

Вы можете использовать "Тип атрибута CDATA" для вашего типа атрибута, я думаю, что это на самом деле то, что происходит в обычном случае, а ваше значение атрибута фактически CDATA: для элемента типа <brush wood="guy&#xA;threep"/> в исходной бинарной байтовой строке, которая является файлом .xml, вы имеете guy&#xA;threep, однако, когда файл обрабатывается, значение атрибута в памяти будет

guy
threep

Ваша проблема может заключаться в 1) создании правильного xml файла и 2) настройке "процессора xml" для получения требуемого результата.

Например, если вы пишете необработанный двоичный файл в качестве xml вручную, вам нужно поместить эти escape-последовательности внутри части значения атрибута в необработанный файл, например, я написал здесь <brush wood="guy&#xA;threep"/> вместо <brush wood="guy (новая строка) threep"/>

Тогда синтаксический анализ действительно даст вам новую строку, я пробовал это с процессором.

Вы можете попробовать его с помощью процессора, такого как саксон, или для бедных людей, например, как браузер, открытие xml в firefox и копирование значения в текстовый редактор - firefox отображает новую строку как пробел, но копирует строку в текстовый редактор показал новую строку. (Возможно, с лучшим подходящим процессором вы сразу можете сохранить прямой вывод.)

Теперь вам нужно только "единственное" - убедиться, что вы правильно справляетесь с этим CDATA. Например, если у вас есть таблица стилей XSL, которая создаст вам html, вы можете использовать что-то вроде этого .xsl для такого xml:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="split">
  <xsl:param name="list"      select="''" />
  <xsl:param name="separator" select="'&#xA;'" />
  <xsl:if test="not($list = '' or $separator = '')">
    <xsl:variable name="head" select="substring-before(concat($list, $separator), $separator)" />
    <xsl:variable name="tail" select="substring-after($list, $separator)" />

    <xsl:value-of select="$head"/>
    <br/><xsl:text>&#xA;</xsl:text>
    <xsl:call-template name="split">
        <xsl:with-param name="list"      select="$tail" />
        <xsl:with-param name="separator" select="$separator" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>


<xsl:template match="brush">
  <html>
  <xsl:call-template name="split">
    <xsl:with-param name="list" select="@wood"/>
  </xsl:call-template>
  </html>
</xsl:template>

</xsl:stylesheet>

Что в браузере или с процессором, например саксоном, с помощью java -jar saxon9he.jar -s:eg2.xml -xsl:eg2.xsl -o:eg2.html saxon home edition 9.5 создаст эту html-подобную вещь:

<html>guy<br>
   threep<br>

</html>  

который будет выглядеть в браузере:

guy
threep

Здесь я использую рекурсивный шаблон "split" из Tomalak, благодаря Mads Hansen, потому что мой целевой процессор не поддерживает ни string-join, ни tokenize, которые только версии 2.0.

Ответ 5

Да, когда вы кодируете содержимое в тегах XML. То есть используйте &amp; &lt; &gt; &quot; &apos;, таким образом он не будет рассматриваться как разметка внутри вашей разметки.

Ответ 6

Мы не можем использовать атрибут CDATA, но мы можем связать html с помощью HTML-кодов. Вот один пример:

чтобы достичь этого: <span class="abc"></span>

используйте XML-код следующим образом:

<xmlNode attibuteName="&lt;span class=&quot;abc&quot;&gt;Your Text&lt;&#47;span&gt;"></xmlNode>