是否可以在XML属性中包含HTML文本或CDATA?

Boo*_*oon 30 html xml

当我尝试将HTML文本或CDATA放入我的XML属性中时,我的解析器一直得到"XML解析器失败:未终止的属性".有没有办法做到这一点,还是标准不允许这样做?

JMP*_*JMP 25

不,CDATA不能是属性的值.它只能在元素内部.

  • 虽然接受的只是引用文档,但您给出了正确的答案,而没有任何来源或支持信息。谁定义CDATA只能在元素内部使用而不能在属性值中使用? (2认同)

Joh*_*ica 13

属性内部只能包含纯文本,没有标签,注释或其他结构化数据.您需要使用字符实体来转义任何特殊字符.例如:

<code text="&lt;a href=&quot;/&quot;&gt;">
Run Code Online (Sandbox Code Playgroud)

这会给text属性赋值<a href="/">.请注意,这只是纯文本,因此如果您想将其视为HTML,则必须自己通过HTML解析器运行该字符串.XML DOM不会text为您解析属性.


Ric*_*ler 9

如果属性不是标记化或枚举类型,则将其作为CDATA处理.有关如何处理属性的详细信息,请参阅可扩展标记语言(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]
Run Code Online (Sandbox Code Playgroud)

...

3.3.3属性值规范化

在将属性的值传递给应用程序或检查其有效性之前,XML处理器必须通过应用下面的算法或通过使用其他方法来规范化属性值,以便传递给应用程序的值与生成的值相同通过算法.

  1. 所有换行必须按照2.11行尾处理中的描述对#xA的输入进行归一化,因此该算法的其余部分对以这种方式归一化的文本进行操作.
  2. 从包含空字符串的标准化值开始.
  3. 对于非标准化属性值中的每个字符,实体引用或字符引用,从第一个开始并继续到最后一个,执行以下操作:
    • 对于字符引用,将引用的字符附加到规范化值.
    • 对于实体引用,递归地将此算法的步骤3应用于实体的替换文本.
    • 对于空格字符(#x20,#xD,#xA,#x9),请在标准化值后附加空格字符(#x20).
    • 对于另一个字符,将字符附加到规范化值.

如果属性类型不是CDATA,则XML处理器必须通过丢弃任何前导和尾随空格(#x20)字符,并通过用单个空格替换空格(#x20)字符序列来进一步处理规范化的属性值(#x20 )性格.

请注意,如果非标准化属性值包含对空格以外的空白字符的字符引用(#x20),则标准化值包含引用的字符本身(#xD,#xA或#x9).这与非标准化值包含空白字符(非参考)的情况形成对比,后者在标准化值中用空格字符(#x20)替换,并且与非标准化值包含实体引用的情况形成对比.替换文本包含空格字符; 在递归处理时,空格字符被标准化值中的空格字符(#x20)替换.

未读取任何声明的所有属性应该由非验证处理器处理,就像声明CDATA一样.

如果属性值包含对未读取声明的实体的引用,则会出错.


n61*_*007 5

CDATA不幸的是,这里有一个模棱两可的说法.有"CDATA部分"" CDATA属性类型".

您的属性值可以是CDATA类型,带有"CDATA属性类型".

这是一个包含"CDATA Section"(又名 CDSect)的xml :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<elemke>
<![CDATA[
foo
]]>
</elemke>
Run Code Online (Sandbox Code Playgroud)

这是一个包含"CDATA属性类型"(as AttType)的xml :

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

<elemke>
<brush wood="guy&#xA;threep"/>
</elemke>
Run Code Online (Sandbox Code Playgroud)

不能"CDATA部分"用于属性值:错误:<brush wood=<![CDATA[foo]]>/>

可以使用"CDATA属性类型"为属性的类型,我认为这实际上是在通常情况下会发生什么,和你的属性值实际上是一个CDATA:一个元素一样<brush wood="guy&#xA;threep"/>,在原始的二进制字节串即是.xml文件,你guy&#xA;threep然而,当文件被处理,在内存中的属性值

guy
threep
Run Code Online (Sandbox Code Playgroud)

您的问题可能在于:1)生成正确的xml文件; 2)配置"xml处理器"以生成所需的输出.

例如,如果您手动将原始二进制文件写为xml,则需要将这些转义放在原始文件的属性值部分中,就像我在<brush wood="guy&#xA;threep"/>这里写的那样,而不是<brush wood="guy (新队) threep"/>

那么解析实际上会给你一个换行符,我用处理器试过了.

你可以像撒克逊或-穷人的试验一个类似浏览器的处理器尝试一下,打开Firefox中的XML 值复制到一个文本编辑器-火狐显示换行符作为一个空间,但复制字符串到文本编辑器显示换行符.(可能使用更合适的处理器,您可以立即保存直接输出.)

现在你需要做的"唯一"事情就是确保你适当地处理这个C​​DATA.例如,如果你有一个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>
Run Code Online (Sandbox Code Playgroud)

在浏览器中或使用java -jar saxon9he.jar -s:eg2.xml -xsl:eg2.xsl -o:eg2.html 撒克逊家庭版9.5的saxon等处理器会产生类似html的东西:

<html>guy<br>
   threep<br>

</html>  
Run Code Online (Sandbox Code Playgroud)

在浏览器中看起来像这样:

guy
threep
Run Code Online (Sandbox Code Playgroud)

感谢Mads Hansen,我在这里使用了来自Tomalak的递归模板"拆分" ,因为我的目标处理器既不支持也不支持2.0版本.string-jointokenize