【问题标题】:XSL: Call a more general template first each time a specific one is calledXSL:每次调用特定模板时,首先调用更通用的模板
【发布时间】:2014-08-06 08:35:29
【问题描述】:

我有一个现有的 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”,我不想更改每个现有的&lt;xsl:template&gt; 来检查此属性...

我尝试添加一个&lt;xsl:template match="*"&gt;,它完成了这项工作,并希望在处理该元素的特定模板之前它会匹配每个元素。但似乎这只适用于未定义特定 xsl:template 的节点。

我也已经阅读了here,它可以创建与&lt;xsl:template match="@specAttr"&gt; 匹配的属性的模板,但是只有在我添加&lt;xsl:apply-templates select="@*"/&gt; 时才会解析此模板。所以我还必须更改每个已经存在的模板并添加这一行。

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

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

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

或者有没有人有其他聪明的想法?

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

提前致谢。

BRgrds, 延斯

【问题讨论】:

  • 你能不能在应用通用(常规)模板之前添加一个&lt;xsl:if test="@specAttr = 'something'&gt;,然后在它之前调用另一个模板?
  • 请发布您现有的 XSLT(最小化到处理给定示例所需的内容)。
  • @Aleski 我可以这样做,但这样我必须调整每个模板以在继续之前首先测试属性,这基本上是我想要避免的。
  • @michael.hor257k 好吧,上面的示例输出非常简化,只是为了让您了解它的外观。实际上,输出包含 FO 标签,这些标签通过 Apache 的 FOP 呈现为 PDF ...

标签: xml templates xslt template-inheritance


【解决方案1】:

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

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

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

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

【讨论】:

  • 这是个好主意。实际上几乎是我正在寻找的东西,它会很好地工作......但是,尝试你的建议我面临的问题是我可以在特定模板之前处理我的通用模板,但实际上有时我必须决定我是否也有添加一个带有列跨度(也可能不同)的新表行...我已经编辑了我的初始帖子试图解释我的意思...也许我必须为某些人创建一个更通用的模板标签和另一个用于其他标签。我再也找不到一种好方法来创建一个在所有位置都可以使用的通用...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多