2

我有一个现有的 xslt 文件,我之前使用多个模板创建了该文件。

现在,需求发生了变化,现在在处理这些特定模板之一之前,我必须检查当前评估节点是否具有特定属性。

如果是,则必须先调用另一个模板,然后再调用特定模板。

所以基本上我的输入 XML 看起来像这样:

<baseNode>
    <textGroup>
        <title>Title here</title>
        <text specAttr="id123456">Text here</text>
        <text>Another text</text>
    </textGroup>
    <paragraph specAttr="id123456">Other text here</paragraph>
    <references>
        <reference specAttr="id123456">
            <data title="1st Reference" ref="http://..." />
        </reference>
        <reference>
            <data title="2nd Reference" ref="http://..." />
        </reference>
        <reference specAttr="id123456">
            <data title="3rd Reference" ref="http://..." />
        </reference>
    </references>
</baseNode>

现在,解析 XML 文件,结果应该是这样的(实际上结果包含 FO 标记,因为我想通过 Apache FOP 创建 PDF,这只是为了简化我想做的事情):

<base>
    <title>Title here</title>
    <text>Next text has this attribute</text>
    <text>Text here</text>
    <text>Another text</text>
    <text>Next text has this attribute</text>
    <p>Other text here</p>
    <table>
        <head>
            <row>
                <cell>Title</cell>
                <cell>URL</cell>
            </row>
        </head>
        <body>
            <row>
                <cell col-span="2">
                    <text>Next text has this attribute</text>
                </cell>
            </row>
            <row>
                <cell>1st Reference</cell>
                <cell>http://...</cell>
            </row>
            <row>
                <cell>2nd Reference</cell>
                <cell>http://...</cell>
            </row>
            <row>
                <cell col-span="2">
                    <text>Next text has this attribute</text>
                </cell>
            </row>
            <row>
                <cell>3rd Reference</cell>
                <cell>http://...</cell>
            </row>
        </body>
    </table>
</base>

好吧... XML 中有几个元素可以具有此属性“ specAttr”,我不想更改每个现有的<xsl:template>以检查此属性...

我尝试添加一个<xsl:template match="*">完成该工作的对象,并希望在处理该元素的特定模板之前它会与每个元素匹配。但似乎这只适用于没有特定xsl:template定义的节点。

我也已经在这里读到,可以创建与属性匹配的模板<xsl:template match="@specAttr">,但只有在我添加<xsl:apply-templates select="@*"/>. 所以我还必须更改每个已经存在的模板并添加这一行。

是否可以创建模板层次结构或模板之间的继承?总是在当前节点的实际模板之前处理父模板?

编辑:查看reference元素,您可以看到我有时还必须知道我必须在哪个位置处理新模板...如果 areference具有此属性,我必须创建一个列跨度为 2 的完整新行(但有时在另一个表中也可能是 4),因为仅添加text节点是不够的...

考虑到这一点,我认为没有办法找到通用的方法来做到这一点......

还是有人有另一个聪明的主意?

如果您需要更多信息或有任何疑问,请随时提问。

提前致谢。

BRgrds,延斯

4

1 回答 1

0

xsl:next-match 指令在这里很有用(或者如果您在 XSLT 1.0 中,xsl:apply-imports)。这使您可以执行类似的操作

<xsl:template match="*[@specAttr]" priority="20">
  <doSomethingSpecial>
    <xsl:next-match/>
  </doSomethingSpecial>
</xsl:template>

下一个匹配指令调用您现有规则的位置,即。在没有这个的情况下会匹配的规则。(apply-imports 略有不同,第二条规则必须在导入的样式表中)。

如果您需要在被覆盖的模板规则创建的输出中间插入一些东西,这不会很好。但是从您的问题陈述中不清楚您是否需要这样做。如果这样做,有时可以通过让覆盖模板规则在变量中捕获覆盖模板规则的输出,然后转换变量的内容来实现。

于 2014-08-06T11:39:55.330 回答