【问题标题】:Making elements always contain only CDATA (embedding XML examples in XML document)使元素始终只包含 CDATA(在 XML 文档中嵌入 XML 示例)
【发布时间】:2012-05-02 14:11:11
【问题描述】:

我正在为我的大学计算俱乐部准备一篇关于 XML 和 XSLT 的简报,我不是专家,但我比任何人都好,而且它只是一个 1 小时的入门。 所以对于我的幻灯片,我想我会使用 XML 文档。 然后我会用 XSLT 2.0 将其变成一系列网页

所以我们有我的源文件

<slideshow>
  <slide title="Example">
    <para>Below is an example of an XML document</para>
    <code> <![CDATA[
<?xml version="1.0"?>
<elephant Name="Fido">
  <head>
    <eyes qty="2" colour="blue"/>
    <trunk/>
    <ears qty="2"/>
  </head>
  <body>
    Thin, ribs showning
  </body>
  <legs qty="4">
    Roughly 1.5m Long
  </legs>
</elephant> ]]>
    </code>
  </slide>
</slideshow>

因为我不希望我的示例构成文档的 XML 结构的一部分,(并且不希望它们被 XSLT 更改) 我有 CDATA 部分。 所以,每次我有一个&lt;code&gt;...&lt;/code&gt; 元素时,它总是写成: &lt;code&gt;&lt;![CDATA[...]]&gt;&lt;/code&gt; 这是信息的重复。

我可以声明每个code 元素只包含(未解析的)字符数据吗?

所以我只写&lt;code&gt;...&lt;/code&gt;,它永远不会尝试解析里面的内容。

似乎可以用 DTD 完成一些事情,也许?


我正在寻找的答案是

使用 &lt;!DECLARE-CDATA-ELEMENT code&gt; 会生成代码元素,而不是解析它们的内容。


你可以用实体来模拟它:

<!ENTITY CodeStart "<code><![CDATA["> 
<!ENTITY CodeEnd "]]></code>">

然后使用:&amp;CodeStart;&lt;don'tParse/&gt;&amp;CodeEmd;


不,不能这样做,但您可以通过...强制所有代码段不包含子元素


不,但您可以像这样进行预处理:...


这些不是答案,它们只是表明答案可能是什么样的 (希望现在更清楚)

【问题讨论】:

  • 不,CDATA 部分之外的标记是常规标记。我不明白为什么你认为让你的代码示例 insifde CDATA 是“信息的重复”......你能解释一下什么是重复的吗?另一种可能性是将样本放在 cmets 中。
  • 它是重复的,因为将它放在 code 元素中应该(具有 code 元素的正确定义)意味着它是 CDATA。请注意,我并不是说 XML 应该将 code 视为特殊关键字。我在问如何使它将代码视为特殊关键字。重复的是,从来没有一个code标签后面没有CDATA标签。
  • 对不起,我一个字都听不懂你在说什么。为什么您认为应该重新编写 W3C XML 规范以纳入您的关于什么是正确的和什么不正确的想法?关于 XML 只有一个正确性——这就是 W3C 规范中所写的内容。
  • 如果您希望 使用任何 CDATA 部分并且仍然将您的示例视为文本,您必须将示例中的每个 &amp;lt;&amp;amp; 字符转义为,分别为&amp;lt;&amp;amp;
  • 确实,我似乎没能说清楚。我并不是说 XML 规范有什么问题。我问这个问题是因为我知道我并不完全了解它(我对 DTD 几乎一无所知)

标签: xml xslt cdata dtd


【解决方案1】:

因为我不希望我的示例构成 XML 结构的一部分 文档,(并且不希望它们被 XSLT 更改)我有 CDATA 部分。

不必使用 CDATA 部分来保护某些 XML 片段不被“XSLT 更改”——只需编写 XSLT 代码,使其复制任何以 @ 为根的子树987654322@元素.

是否可以声明每个代码元素只包含 (未解析的)字符数据?

是的,但是 XSLT 不要求源 XML 文档或处理结果有 DTD(Schema-aware XSLT 2.0 可以验证这些甚至是中间结果,但它只适用于 XML Schema (XSD) ),如果有这样的 DTD,XSLT 不使用任何类型信息(唯一的例外是存在 ID 属性这一事实)。因此,提供这样的 DTD 不会有任何帮助。

此外,这样的 DTD 将被违反,除非您在 code 的子文本节点中至少转义每个 &amp;&lt; 字符

来自W3C XML specification

"[定义:所有非标记文本构成文档的字符数据。] & 符号(&)和左角 括号 (。”

【讨论】:

  • 如果我的 Xml 片段包含 &lt;?xml version="1.0"?&gt; 标头,那么在您的第一个解决方案中,我会遇到问题,对吧?除此之外,它运行良好。这是我最初考虑的。以及可能将它们放在不同的名称空间中? (解决 XSLT 获取名称的另一个问题)
  • @Oxinabox:这不是“标题”——这是XML 声明。没有必要(因为 version="1.0" 是默认值),所以不要包含任何 XML 声明。
【解决方案2】:

我明白你关于code 和 CDATA 部分的关系的观点:如果你从来没有一个没有另一个,那么其中一个没有携带太多信息。但是不,其他答案是完全正确的:没有办法声明应该以不同方式解析 code 元素。

值得一提的是,SGML DTD 确实能够使用CDATA 关键字声明元素,其含义是“此元素中的所有内容都是字符数据,而不是标记,因此此处不识别分隔符”。当然,您确实想识别元素的结尾,因此事情很快就会变得相当复杂,并且CDATA 声明结果(即使在所有复杂情况之后)对于您描述的用例来说并不是很好。

因此,即使我们没有 Andrew Cooke 提到的动机,我们也可能在 XML 中拥有深层的 CDATA 元素声明:任何允许声明更改解析器行为的工具都使得在不读取 DTD 的情况下无法解析。

所以:您反对的冗余本质上是您针对两个不同受众这一事实的结果:CDATA 标记部分与解析器讨论要解析的内容和方式,code 元素与关于文档逻辑结构的下游应用程序(例如您的 XSLT 样式表)。简单过程的仔细分层有时会增加冗长的一般原则的一个小例子。

希望你的演讲顺利。

【讨论】:

    【解决方案3】:

    首先,我知道没有机制可以做到这一点。

    其次,根据我对 xml 标准的有限理解,我认为您想要的东西不存在。 xml 规范有一个“格式良好”的概念,适用于没有(或“之前”,如果你喜欢)DTD 的 xml 文档,并且没有 CDATA 的文档格式不正确。

    换句话说,xml文档必须自己遵循一定的规则;您要求的是 DTD 放宽/更改这些规则,但 DTD 仅提供除了格式正确(导致“有效”文档)之外的进一步检查,它们不能更改格式正确的要求。

    但我不是伟大的 xml 专家...

    ps 问题在于&lt;?xml... ?&gt; 部分;正如另一个答案所说,您可以将 xml 元素直接嵌入到您的文档中(在这种情况下,如果您想在“包含”和“嵌入”xml 之间做出更明确的区别,请查看 xml 命名空间)。

    【讨论】:

    • 谢谢,我希望也许 DTD 会有一个解决方案。因为它们确实允许创建实体,(严格来说,这不是验证目标的一部分)
    【解决方案4】:

    我倾向于不嵌入示例文档,而是引用它们:

    <code ref="example1.xml"/>
    

    【讨论】:

    • 也许是更长的,但我的大部分都不到 4 行。 (有些只是“这是一个开始标签&lt;ele&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2014-10-06
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    相关资源
    最近更新 更多