强制HTML Tidy输出XML(而不是XHTML),或强制XSLTproc解析XHTML文件

时间:2011-09-04 19:12:52

标签: xslt tidy

我需要使用XSLT处理大量HTML文件,使用XML文件选择哪些HTML文件,以及我们正在使用它们做什么。

我试过了:

  1. 使用HTML Tidy转换HTML - > XHTML / XML
  2. 在XSLT中使用文档(文件名)来读取特定的XHTML / XML文件
  3. ...使用标准节点集命令来访问例如“HTML /体/ *”
  4. 这不起作用,因为:

    1. 似乎XSLT(尝试过:libXSLT / xsltproc ...和Saxon)无法将XHTML文档作为外部文件处理(它看到xhtml DOCTYPE,并拒绝将其解析为节点)。
    2. 很好(我想)...... XHTML只是XML,我只需要通过HTML Tidy说出来:

      “output-xml yes ... output-html no ... output-xhtml no”

      ...但是,如果您尝试这样做,HTML Tidy会忽略您,并强制使用html :(。如果输入是XML开头,它似乎只是输出XML文件的硬编码。

      有关如何:

      的任何想法
      1. 强制HTML Tidy遵守命令行参数,并设置我要求的文档类型
      2. 强制XSLTproc将xhtml DOCTYPE解析为xml
      3. ......其他一些狡猾的方法会起作用吗?
      4. 注意:这必须在OS X上运行 - 它是iOS应用程序构建过程的一部分。这应该不是一个大问题,但是任何仅限Windows的工具都不可用。我想用标准的开源跨平台工具(如整洁,libxslt等)实现这一目标

5 个答案:

答案 0 :(得分:2)

我终于发现了为什么XSLTproc / Saxon拒绝解析文件,如果它们是用DOCTYPE html传入的话:

  

外部文件的DOCTYPE改变了他们如何解释   xmlns(命名空间)指令。 Tidy宣布(正确)   “xmlns = ... xhtml:namespace” - 所以我所有的节点名都是......我不知道:不存在? ...在我的XSLT中。 XSLT只是忽略它们,就好像它们不存在一样 - 它需要我提供与同一命名空间的兼容映射

......奇怪的是,如果DOCTYPE是xml,那么他们很乐意忽略xmlns命令 - 或者他们允许我通过非限定名称引用节点。这让我误以为他们忽略了xhtml DOCTYPE版本中的节点集。

所以,“解决方案”是这样的:

  1. 修改您的XSLT样式表以便导入“xhtml”命名空间 - 注意:这是必需的,以便您可以引用外部文件中的节点
  2. 在每个节点上写下你所有的XSL匹配/选择/模板规则和“xhtml”前缀(我认为每个属性都是?)
  3. 让Tidy输出任何想要的东西:没关系,只要你在那里有命名空间支持就可以工作
  4. 示例代码:

    1. 您的样式表来自:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      

      ......对此:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
      
    2. 您的select / match / document-import来自:

      <xsl:copy-of select="document('html-files/file1.htm')/html/body"/>
      

      ......对此:

      <xsl:copy-of select="document('html-files/file1.htm')/xhtml:html/xhtml:body"/>
      
    3. 注意:要明确:如果忽略名称空间,那么看起来XSLT 将在unDOCTYPED文件上运行,即使它们中有名称空间。不要因为看起来像是因为它看起来是错误而认为你的XSLT是正确的。)

答案 1 :(得分:0)

XHTML XML(如果它有效)。

要将XHTML作为XML处理,您不得将其作为“text / html”MIME提供。请改用application / xhtml + xml(请记住,IE6不支持渲染它,并会提示您网站的下载窗口。)

在PHP中,您是否使用header()函数将其作为xhtml + xml提供。

我认为这应该可以解决问题:

header('Content-Type: application/xhtml+xml');

这有帮助吗?

答案 2 :(得分:0)

如果你运行xsltproc --help,在接受的输入标志中有一个非常引人注目的名为--html,它应该告诉xsltproc

  

- html:输入文档是HTML文件

但是,为了实现这一点,您必须首先拥有有效的 HTML文件。所以你可能想先把它们整理一下。

答案 3 :(得分:0)

已经有一段时间了,但我记得尝试使用HTMLTidy来为XSLT准备HTML文件,并且在尝试“很好地形成”HTML时它很容易放弃。然后我找到了TagSoup,非常高兴。

  

TagSoup还包括一个命令行处理器,它可以读取HTML文件并生成干净的HTML或格式良好的XML,它与XHTML非常接近。

我不知道您是否受HTMLTidy的约束,但如果不这样做:http://home.ccil.org/~cowan/tagsoup/

举个例子,这是一个糟糕的HTML文件:

<body>
  <p>Testing
</body>

这是tagsoup命令及其输出:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html bad.html 
src: bad.html
<html><body>
  <p>Testing
</p></body></html>

修改01

以下是tagsoup处理DOCTYPE的方法。

这是一个错误的HTML文件,其中包含有效的DOCTYPE:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
  <p>Testing
</body>
</html>

以下是tagsoup如何处理它:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html bad.html 
src: bad.html
<html><body>
  <p>Testing
</p></body></html>

直到你明确地将DOCTYPE传递给tagsoup,它才会尝试输出一个:

~ zyoung$ java -jar /usr/local/tagsoup-1.2.jar --html --doctype-public=html bad.html 
src: bad.html
<!DOCTYPE  PUBLIC "html" "">
<html><body>
  <p>Testing
</p></body></html>

我希望这有帮助,
扎卡里

答案 4 :(得分:0)

我认为主要问题是由XML目录doctype声明给出的。您可以通过删除输入XHTML中的外部实体引用来测试这一点,并查看处理器是否正确使用它。

我会这样做:

  • 将Tidy与doctype omit选项一起使用。
  • 按照here
  • 所述在XSLT端添加Doctype

主要问题是Saxon和xsltproc没有任何禁用外部实体解析的选项。具有选项-xe的MSXSL.exe命令行实用程序支持此功能。