泛化 XSLT 代码
Generalizing XSLT code
我正在尝试了解概括 XSLT 模板的不同可能性,以便在不同的地方重用它们。到目前为止,我有两个案例我不知道如何进行。
案例 1 - 来源 XML 可能包含节点 Foo1, Foo2, ..., Foo10
(但不一定包含任何或所有节点)。例如,
<Foo1>some value</Foo1>
<Foo3>some other value</Foo3>
我需要创建如下节点:
<Bar number="1">some value</Bar>
<Bar number="3">some other value</Bar>
我目前的 XSLT 非常简单:
<xsl:if test="Foo1 != ''">
<xsl:element name="Bar">
<xsl:attribute name="number">1</xsl:attribute>
<xsl:value-of select="Foo1"/>
</xsl:element>
</xsl:if>
但我显然需要 10 个这样的代码块。我如何概括这一点?
案例 2 - 在源代码 XML 中,我有几个基本相同结构的节点:
<Foo>
<item>
<Start>2015-06-01</Start>
<End>9999-12-31</End>
<Foo>00000008</Foo>
</item> <!-- 0..n items -->
</Foo>
节点的名称不同Foo
,但其余的保持不变。我需要构建的结构如下所示:
<Bars>
<Bar From="2015-06-01" To="9999-12-31">
<Value>00000008</Value>
</Bar>
</Bars>
这是我的 XSLT 尝试,但我再次需要许多彼此非常相似的模板:
<xsl:element name="Bars>
<apply-templates select="Foo"/>
</xsl:element>
...
<xsl:template match="Foo/item">
<xsl:element name="Bar">
<xsl:attribute name="From">
<xsl:call-template name="convertDate">
<xsl:with-param name="theDate" select="Start"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="To">
<xsl:call-template name="convertDate">
<xsl:with-param name="theDate" select="End"/>
</xsl:call-template>
</xsl:attribute>
<xsl:element name="Value">
<xsl:value-of select="Foo"/>
</xsl:element>
</xsl:element>
</xsl:template>
再一次,我有几个模板,它们看起来都非常相似(即,它们仅在 Foo
、Bar
和 [=20= 的名称上有所不同) ] 元素)。是否有机会概括这一点,即提供一个可以处理所有这些情况的模板?
您可以使用
<xsl:template match="*[starts-with(local-name(), 'Foo')]">
<Bar number="{translate(local-name(), translate(local-name(), '1234567890', ''), '')}">
<xsl:apply-templates/>
</Bar>
</xsl:template>
第一个样本。
转换
<item>
<Start>2015-06-01</Start>
<End>9999-12-31</End>
<Foo>00000008</Foo>
</item>
到
<Bar From="2015-06-01" To="9999-12-31">
<Value>00000008</Value>
</Bar>
你可以使用
<xsl:template match="item">
<Bar From="{Start}" To="{End}">
<xsl:value-of select="Foo"/>
</Bar>
</xsl:template>
我正在尝试了解概括 XSLT 模板的不同可能性,以便在不同的地方重用它们。到目前为止,我有两个案例我不知道如何进行。
案例 1 - 来源 XML 可能包含节点 Foo1, Foo2, ..., Foo10
(但不一定包含任何或所有节点)。例如,
<Foo1>some value</Foo1>
<Foo3>some other value</Foo3>
我需要创建如下节点:
<Bar number="1">some value</Bar>
<Bar number="3">some other value</Bar>
我目前的 XSLT 非常简单:
<xsl:if test="Foo1 != ''">
<xsl:element name="Bar">
<xsl:attribute name="number">1</xsl:attribute>
<xsl:value-of select="Foo1"/>
</xsl:element>
</xsl:if>
但我显然需要 10 个这样的代码块。我如何概括这一点?
案例 2 - 在源代码 XML 中,我有几个基本相同结构的节点:
<Foo>
<item>
<Start>2015-06-01</Start>
<End>9999-12-31</End>
<Foo>00000008</Foo>
</item> <!-- 0..n items -->
</Foo>
节点的名称不同Foo
,但其余的保持不变。我需要构建的结构如下所示:
<Bars>
<Bar From="2015-06-01" To="9999-12-31">
<Value>00000008</Value>
</Bar>
</Bars>
这是我的 XSLT 尝试,但我再次需要许多彼此非常相似的模板:
<xsl:element name="Bars>
<apply-templates select="Foo"/>
</xsl:element>
...
<xsl:template match="Foo/item">
<xsl:element name="Bar">
<xsl:attribute name="From">
<xsl:call-template name="convertDate">
<xsl:with-param name="theDate" select="Start"/>
</xsl:call-template>
</xsl:attribute>
<xsl:attribute name="To">
<xsl:call-template name="convertDate">
<xsl:with-param name="theDate" select="End"/>
</xsl:call-template>
</xsl:attribute>
<xsl:element name="Value">
<xsl:value-of select="Foo"/>
</xsl:element>
</xsl:element>
</xsl:template>
再一次,我有几个模板,它们看起来都非常相似(即,它们仅在 Foo
、Bar
和 [=20= 的名称上有所不同) ] 元素)。是否有机会概括这一点,即提供一个可以处理所有这些情况的模板?
您可以使用
<xsl:template match="*[starts-with(local-name(), 'Foo')]">
<Bar number="{translate(local-name(), translate(local-name(), '1234567890', ''), '')}">
<xsl:apply-templates/>
</Bar>
</xsl:template>
第一个样本。
转换
<item>
<Start>2015-06-01</Start>
<End>9999-12-31</End>
<Foo>00000008</Foo>
</item>
到
<Bar From="2015-06-01" To="9999-12-31">
<Value>00000008</Value>
</Bar>
你可以使用
<xsl:template match="item">
<Bar From="{Start}" To="{End}">
<xsl:value-of select="Foo"/>
</Bar>
</xsl:template>