使用XSLT递归合并XHTML文件为一个XHTML文件

5
我正在尝试创建一个XSL样式表,允许将从另一个XHTML文件引用的XHTML文件合并。反过来,任何从所引用的文件中引用的XHTML文件也应该被合并,依此类推。因此,可以递归地将由起始XHTML文件直接或间接引用的所有XHTML合并到一个XHTML文件中。引用是严格分层的。
例如:
文件a.html:
<html>
    <body>Text1<br/><a href="b.html">Link</a></body>
</html>

文件 b.html:

<html>
    <body>Text2<br/><a href="c.html">Link</a></body>
</html>

文件 c.html:

<html>
    <body>Text3<br/></body>
</html>

从a.html开始合并后的结果文件:

<html>
    <body>Text1<br/>Text2<br/>Text3<br/></body>
</html>

我不确定如何使用XSLT解决这个问题。欢迎提供任何帮助。


+1 - 很好的问题,有很棒的简短示例。 - Daniel Haley
3个回答

3

使用 document() 函数,如下所示:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--IDENTITY TRANSFORM-->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="a">
    <xsl:apply-templates select="document(@href)/html/body/node()"/>
  </xsl:template>

</xsl:stylesheet>

使用您的三个HTML文件,并以作为输入,将产生以下输出结果:
<html>
  <body>Text1<br/>Text2<br/>Text3<br/>
  </body>
</html>

此外,真正使这成为可能的是身份转换。它会将任何未被其他模板匹配的内容传递而不做改变。

0

这个转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" omit-xml-declaration="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="a">
  <xsl:apply-templates select=
  "document(@href)/*/body/node()"/>
 </xsl:template>
</xsl:stylesheet>

当应用于文件"a.html"时:

<html>
    <body>Text1<br/><a href="b.html">Link</a></body>
</html>

产生所需、正确的结果:

<html><body>Text1<br/>Text2<br/>Text3<br/></body></html>

解释:

  1. 身份规则会将每个节点“原样”复制。

  2. 唯一的覆盖模板匹配任何a元素。

  3. 在此模板中,启动处理a元素的href属性指向的文档。使用标准的XSLT函数document()是必不可少的。


0

这可能有点棘手,但是请查看document()函数。

我看到的例子展示如何在输出中包含另一个文档,但我没有看到任何示例可以让您在同一调用期间开始转换该文档。但是我也没有自己尝试过。
如果`document()`不能让你递归地将你的变换嵌套到其他文档中,那么你可以在循环中调用你的变换,并编写可重复调用的变换。然后你需要某种方式来检查何时可以停止转换。
一个知道何时应该停止的方法是在源文档和目标文档之间进行比较。
另一种方法是在文档顶部放置一个元素,如果找到任何子文档,则删除该元素。然后只需检查该元素是否存在即可。
但也许有一种方法可以通过包含的子文档继续变换。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接