将样式表应用于样式表

  • 本文关键字:样式 应用于 xslt
  • 更新时间 :
  • 英文 :


我正在编辑一个大型Microsoft InfoPath文档。InfoPath在内部使用XSLT进行表单布局。GUI非常麻烦,我想通过使用XSLT编辑内部样式表来加快这个过程。因此,这里有一个有趣的XSLT问题:如何将一个XSLT样式表应用于另一个?这里有一个开始:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="select">
    ...
  <xsl:template>
</xsl:stylesheet>

也就是说,我复制所有内容,但更改<选择>元素。在"选择"模板中,我想要一块XSLT。但是,我不希望处理XSLT。但是我确实希望它有XSLT名称空间,这样输出仍然可以作为样式表工作。

我想我可以将XSLT块的名称空间URI设置为任何值,然后将其更改为XSLT名称空间URI,但这需要额外的步骤。有更好的方法吗?

这是<xsl:namespace-alias> 的目的

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:xslout="urn:dummy"
                exclude-result-prefixes="xslout">
  <xsl:namespace-alias stylesheet-prefix="xslout" result-prefix="xsl" />
  <xsl:output method="xml" indent="yes"/>
  <!-- ... -->
  <xsl:template match="select">
    <xslout:value-of select="{@valueXpath}" />
  <xsl:template>
</xsl:stylesheet>

这里,样式表中的任何xslout:元素都将在输出中变为xsl:,并且这些元素中的任何属性值模板都将由这个样式表处理(因此在上面的例子中,<select valueXpath="@foo" />将生成<xsl:value-of select="@foo" />作为输出)。如果你想在输出中放入AVT,你必须将大括号加倍

<xslout:element name="{{@elementName}}" />

如果你已经有了不想重写的<xsl:...>内容块,那么你可以使用不同的前缀,例如

<?xml version="1.0" encoding="utf-8"?>
<sty:stylesheet xmlns:sty="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:xsl="urn:dummy"
                exclude-result-prefixes="xsl">
  <sty:namespace-alias stylesheet-prefix="xsl" result-prefix="sty" />
  <sty:template match="select">
    <xsl:value-of select="{@valueXpath}" />
  <sty:template>

尽管关于AVT的注释仍然有效。

如果您只想将一块XSLT代码逐字复制到select元素中(而不是根据select元素的内容生成它),一个可能更简单的替代方案是将该XSLT代码放在另一个文件中,并使用document函数

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="select">
    <xsl:copy-of select="document('to-insert.xml')/*/node()" />
  <xsl:template>
</xsl:stylesheet>

其中to-insert.xml包含类似的内容

<data xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:for-each select="*">
    <!-- ... -->
  </xsl:for-each>
</data>

要将XSLT元素输出到结果XML文档,您不能按原样使用这些元素,因为正如您所说,它们将作为XSLT处理。但是,您可以使用元素<xsl:element>输出XSLT元素。

例如,

<xsl:template match="select">
    <xsl:element name="xsl:apply-templates">
        <xsl:attribute name="select">*</xsl:attribute>
    </xsl:element>
<xsl:template>

这将为每个选择元素输出

<xsl:apply-templates select="*" />

您可以使用<xsl:element>和<xsl:attribute>来构建要输出的XSLT代码。

UPDATE:根据您的场景,您有一个需要在选择模板中输出的大型XSLT代码,因此用<xsl:element>和<xsl:attribute>。但是您不需要花费那么多时间,因为您可以编写XSL模板来将模板匹配select中的XSLT转换为使用<xsl:element>和<xsl:attribute>。

以下代码可以做到这一点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:myname="http://www.myname.co.uk/def">
    <xsl:output method="xml" indent="no"/>

    <!-- Copy by default all elements which do not belong to the xsl namespace -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>
    <!-- Match elements which their namespace match the namespace matched with xsl -->
    <xsl:template match="xsl:*">
        <!-- Transform all the elements to xsl:element name="xsl:element" nodes -->
        <xsl:element name="xsl:element">
            <xsl:attribute name="name">
                <xsl:value-of select="name()" />
            </xsl:attribute>
            <xsl:apply-templates select="@*" mode="xsl-attr" />
            <xsl:apply-templates select="node()" />
        </xsl:element>
    </xsl:template>
    <!-- Transform all the attributes to xsl:element name="xsl:attribute" -->
    <xsl:template match="@*" mode="xsl-attr">
        <xsl:element name="xsl:attribute">
            <xsl:attribute name="name">
                <xsl:value-of select="local-name()" />
            </xsl:attribute>
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

因此,您可以将从转换中获得的代码复制并粘贴到与select元素匹配的模板中。

相关内容

  • 没有找到相关文章

最新更新