3

我有文件grandchild.xml,它的结果用granchild.xsl处理后必须转发到child.xsl,然后必须最终由parent.xsl处理输出。

我尝试向xml-stylesheet结果文档添加一个元素,期望它被引用的 XSL 样式表处理,但没有发生任何事情。

完成这项任务的正确声明是什么?我在互联网上搜索了很多,没有结果。

4

2 回答 2

1

以下是浏览器中的多遍转换示例

让我们有这个源 XML 文档

<?xml-stylesheet title="XSL_formatting"
  type="text/xsl" href="MultiPassBrowser.xsl"?>
<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

让我们进行这两个 XSLT 转换

MultiPassBrowser1.xsl

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

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

 <xsl:template match="num/text()">
  <xsl:value-of select=". *2"/>
 </xsl:template>
</xsl:stylesheet>

MultiPassBrowser2.xsl

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

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

 <xsl:template match="num" mode="pass2">
  <p><xsl:value-of select=". +1"/></p>
 </xsl:template>
</xsl:stylesheet>

第一个转换“按原样”复制 XML 文档,但每个num元素的字符串值都乘以 2。

第二个转换“按原样”复制 XML 文档,但每个num元素的字符串值都递增。

如果将第二个变换应用于第一个变换的结果,则从初始num元素获得的最终值必须是 3、5、7、...、21。

这是将这两者粘合在一起的转换

MultiPassBrowser.xsl

<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
 exclude-result-prefixes="ext msxsl">
 <xsl:import href="file:///C:/Temp/delete/MultiPassBrowser1.xsl"/>
 <xsl:import href="file:///C:/Temp/delete/MultiPassBrowser2.xsl"/>
 <xsl:output method="html"/>
 <xsl:strip-space elements="*"/>

 <msxsl:script language="JScript" implements-prefix="ext">
     this['node-set'] =  function (x) {
      return x;
      }
 </msxsl:script>

 <xsl:template match="/">
  <html>
      <xsl:variable name="vrtfPass1">
        <xsl:apply-templates select="/*"/>
      </xsl:variable>

      <xsl:apply-templates select="ext:node-set($vrtfPass1)/*/*"
                           mode="pass2"/>
  </html>
 </xsl:template>
</xsl:stylesheet>

当使用 IE、Firefox、Safari 和 Opera 打开 XML 文件时,结果是正确的、预期的结果

<html>
   <p>3</p>
   <p>5</p>
   <p>7</p>
   <p>9</p>
   <p>11</p>
   <p>13</p>
   <p>15</p>
   <p>17</p>
   <p>19</p>
   <p>21</p>
</html>

说明

  1. 主要样式表模块(XML 文档 PI 中引用的那个)导入包含单独转换的两个样式表模块。

  2. 第一次转换的结果被捕获在 variavle 中$vrtfPass1

  3. 在 XSLT 1.0 中,此类变量属于臭名昭著的“RTF”(结果树片段)类型,不能直接操作(只能string()在 RTF 上使用复制和函数)。在这里,我们使用xxx:node-set()扩展功能的可移植变体,它可以在 IE 和其他四种主要浏览器中运行。这个可移植的扩展首先由@DavidCarlisle 提出,原文可以在他的博客中找到。

  4. 然后将模式“pass2”中的模板应用于节点集,我们在上面的步骤中将 RTF 变量转换为该节点集。第二个导入的样式表模块中的所有模板都处于“pass2”模式,因此它们被选中执行。

  5. 最终结果产生。

于 2012-08-17T02:39:03.247 回答
0

除非有人知道得更好,否则我相信在浏览器上递归处理 XSLT 输出的能力是不可能的。

为了证明这一点,我刚刚在 IE8、FF14 和 Chrome 中尝试了以下...

level1.xml

<?xml version="1.0" encoding="utf-8" ?> 
<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="level1.xsl"?>
<data>
  <id>Level 1 data</id>
</data>

level1.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
     <?xml-stylesheet title="XSL_formatting" type="text/xsl" href="level2.xsl"?>
     <data2>
       <id2>Level 2: <xsl:value-of select="/data/id"/></id2>
     </data2>
   </xsl:template>   
</xsl:stylesheet>

level2.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
     <html>
       <body>
         <b>Level 3:</b> <xsl:value-of select="/data2/id2"/>
       </body>
     </html>
   </xsl:template>   
</xsl:stylesheet>

所有 3 个浏览器的结果只是显示Level 2: Level 1 Data.

于 2012-08-14T16:56:21.843 回答