【发布时间】:2016-10-10 15:14:54
【问题描述】:
我有一个非常统一的输入 XML,我需要将其转换为完全自定义的 XML。 为此,我尝试在 XSL 的不同位置调用名称模板。我的问题是调用模板时无法选择节点,导致这样的代码非常长且冗余(简化示例来说明问题):
<xsl:template match="/">
<workspace>
<data>
<xsl:apply-templates select="/data/data_set[@id='id1']" />
<xsl:apply-templates select="/data/data_set[@id='id2']" />
<xsl:apply-templates select="/data/data_set[@id='id3']" />
</data>
</workspace>
</xsl:template>
<xsl:template match="/data/data_set[@id='id1']">
<xsl:call-template name="attribute">
<xsl:with-param name="id" select="'some_value1'" />
<xsl:with-param name="type" select="'some_value2'" />
</xsl:call-template>
</xsl:template>
<xsl:template match="/data/data_set[@id='id2']">
<xsl:call-template name="attribute">
<xsl:with-param name="id" select="'some_other_value1'" />
<xsl:with-param name="type" select="'some_other_value2'" />
</xsl:call-template>
</xsl:template>
<xsl:template match="/data/data_set[@id='id3']">
<xsl:call-template name="attribute">
<xsl:with-param name="id" select="'some_third_value1'" />
<xsl:with-param name="type" select="'some_third_value2'" />
</xsl:call-template>
</xsl:template>
<xsl:template name="attribute">
<xsl:param name="id" />
<xsl:param name="type" />
<!-- Write the attribute node -->
<attribute attribute_id="{$id}" attribute_value_type="{$type}">
<xsl:for-each select="data_point">
<element>
<xsl:attribute name="id"><xsl:value-of select="@key" /></xsl:attribute>
<xsl:attribute name="{$type}"><xsl:value-of select="@value" /></xsl:attribute>
</element>
</xsl:for-each>
</attribute>
</xsl:template>
有没有更好的方法来避免所有这些冗余?我想要写这样的东西(但这不是有效的 XSLT),因为你不能在调用模板中进行选择。
<xsl:template match="/">
<workspace>
<data>
<xsl:call-template name="attribute" select="/data/data_set[@id='id1']">
<xsl:with-param name="id" select="'some_value1'" />
<xsl:with-param name="type" select="'some_value2'" />
</xsl:call-template>
<xsl:call-template name="attribute" select="/data/data_set[@id='id2']">
<xsl:with-param name="id" select="'some_other_value1'" />
<xsl:with-param name="type" select="'some_other_value2'" />
</xsl:call-template>
<xsl:call-template name="attribute" select="/data/data_set[@id='id3']">
<xsl:with-param name="id" select="'some_third_value1'" />
<xsl:with-param name="type" select="'some_thrid_value2'" />
</xsl:call-template>
</data>
</workspace>
</xsl:template>
示例输入:
<?xml version="1.0" encoding="utf-8"?>
<data>
<data_set id="id1">
<data_point value="1" key="4"/>
<data_point value="2" key="5"/>
<data_point value="3" key="6"/>
</data_set>
<data_set id="id2">
<data_point value="1" key="4"/>
<data_point value="2" key="5"/>
<data_point value="3" key="6"/>
</data_set>
<data_set id="id3">
<data_point value="1" key="4"/>
<data_point value="2" key="5"/>
<data_point value="3" key="6"/>
</data_set>
</data>
示例输出:
<?xml version="1.0" encoding="utf-8"?>
<workspace>
<data>
<attribute id="some_value1" type="some_value2">
<element id="4" some_value2="1"/>
<element id="5" some_value2="2"/>
<element id="6" some_value2="3"/>
</attribute>
<attribute id="some_other_value1" type="some_other_value2">
<element id="4" some_other_value2="1"/>
<element id="5" some_other_value2="2"/>
<element id="6" some_other_value2="3"/>
</attribute>
<attribute id="some_third_value1" type="some_third_value2">
<element id="4" some_third_value2="1"/>
<element id="5" some_third_value2="2"/>
<element id="6" some_third_value2="3"/>
</attribute>
</data>
</workspace>
【问题讨论】:
-
如果包含输入和预期输出的示例,问题会更好地说明。
-
嗯,这仍然是一个谜,因为我们看不到被调用的模板做了什么。这些参数是完全任意的吗?或者它们可能以某种方式源自
@id? -
是否可以看到调用模板?也许我们可以解决这个问题。所以冗余也会减少。但我们看不到的,我们无法改变。
-
参数甚至模板都可能因 id 而异。
-
@user3124206 也许您应该使用查找来确定它们。顺便说一句,您的示例显示为每个 id 调用相同的模板。