【问题标题】:XSL -> XHTML with doctype set in the template, won't transformXSL -> XHTML 在模板中设置了 doctype,不会转换
【发布时间】:2011-10-19 00:46:37
【问题描述】:

我正在尝试从 XML 数据生成有效的 XHTML 文档。
我正在使用 MSXML 对象库,而不是 .NET。 使用 .NET 没有问题,转换很好。

我的 XSL 模板有这个:

<xsl:output
  method="xml"
  omit-xml-declaration="no"
  indent="no"
  version="1.0"
  encoding="utf-8"
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
/>

接着说:

<xsl:template match="/root">
  <html xmlns="http://www.w3.org/1999/xhtml">
  ...
  </html>
</xsl:template>

问题来了。

  • 如果我使用 MSXML2.DOMDocument40,MSXML 拒绝生成 XHTML,因为

    此元素上的属性“{xmlns}”未在 DTD/Schema 中定义。

    显然,模板正文中的其中一个 HTML 标记不允许具有它从 &lt;html&gt; 继承的命名空间。但是 MSXML 不会告诉我是哪个标签。

    如果我只是从模板中删除所有内容并转储包含在&lt;p&gt; 中的 XML 数据,那么它转换得很好。显然,&lt;p&gt; 被允许拥有xmlns

    那是什么标签,它毁了我的一切?

  • 如果我使用MSXML2.DOMDocument60,我首先要说:

    xmlTransformedResult.setProperty("ProhibitDTD", False)
    

    ,否则我会得到“禁止 DTD”。

    设置了该设置,我得到:

    使用了元素“html”,但未在 DTD/Schema 中声明。

    我该如何解决这个问题?

  • 如果我使用 .NET 转换,一切都很好。生成的文档以

    开头
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    

现在,我可以从模板中删除doctype-publicdoctype-system,只生成纯XML,然后手动为其添加标题。但我不想。完成这项工作的正确方法是什么?

【问题讨论】:

  • 如何使用 MSXML 和脚本?您究竟使用哪个 API?如果您使用 transformToObject 并且 xmlTransformedResult 是一个 MSXML DOM 文档,那么在运行转换之前尝试设置 xmlTransformedResult.validateOnParse = false
  • @Martin 是的。我使用来自 VB6 和 VBA 的transformNodeToObjectvalidateOnParse 确实有帮助,但那是正确的方法吗? (如果问题出在 MSXML 中,我会接受。否则,我更愿意修复我的代码。)

标签: xml xslt xhtml doctype msxml


【解决方案1】:

我认为 MSXML 6 的问题在于默认情况下它既不允许 DTD,也不加载它们(或一般的任何外部资源)。因此,为避免验证消息,您需要同时设置两者(我使用的是 JScript 语法,请根据您选择的语言进行调整):

xmlTransformedResult.resolveExternals = true;
xmlTraansformedResult.setProperty('ProhibitDTD', false);

那么我认为您不会收到验证错误。至少只要 W3C 将提供 XHTML DTD 文件,我认为当您以编程方式执行此操作时,您可能会遇到错误,但这不依赖于 MSXML,这只是 W3C 避免过多流量的策略获取此类 DTD 的每个人的服务器。

【讨论】:

  • 哎哟。我希望它去任何地方并实际下载 dtds。事实上,当我在玩它的时候,我看到它居然在网上流传,我还是很惊讶的。我曾经考虑过这四个已知的、预先存在的标准 DTD(HTML/XML 严格/过渡),就像标准 XML 命名空间一样,尽管命名空间看起来像 url,但没有理智的处理器会下载。顺便说一句,它失败了很多,它必须等待大约 30 秒才能失败,这显然会大大减慢一切。
  • 好吧,您不必下载 DTD 并针对它们进行验证,只需让 resolveExternals 的 MSXML 默认值为 false,按照最初的建议将 validateOnParse 设置为 false,我认为您可以写出XHTML 就好了。至于 XML 解析器已知的 XHTML DTD,不,我不认为 MSXML 具有这些的内置知识。 .NET 4.0 允许您使用msdn.microsoft.com/en-us/library/…,但我不知道在 MSXML 方面有任何可比性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-12-23
相关资源
最近更新 更多