输入xml文件:
<Config>
<Fix title="title" description="description" React="200" Lock="E0" Hold="50">
<Name type="type" value="value" Hold="50">
<Image select="2" readonly="false" />
</Name>
</Fix>
</Config>
"updates.xml"获取输入文件更新的文件- Lock, React和Hold标签,const="?"属性:
<Macro>
<Item key="Element">
<tag1 title="title1" description="description1" />
<tag2 title="title2" description="description2" />
<tag3 title="title3" description="description3" />
</Item>
<Item key="Attribute">
<Lock title="title4" const="?" description="description4" />
<React title="title5" const="?" description="description5" />
<Hold title="title6" const="?" description="description6" />
</Item>
</Macro>
如果输入文件包含来自"updates.xml"文件,然后从"updates.xml"文件被复制到它。此外,如果输入文件中的标记具有Lock、React或Hold属性,那么在转换之后,这些属性将成为子标记,而不是属性,并且输入文件中的Lock、React或Hold属性的值将分别在转换之后成为文件的Lock、React或Hold标记的const属性的值。经过XSLT1.0转换后的文件应该如下所示:
<Config>
<Fix title="title" description="description">
<Lock const="E0" title="title4" description="description4" />
<React const="200" title="title5" description="description5" />
<Hold const="50" title="title6" description="description6" />
<Name type="type" value="value">
<Hold const="50" title="title6" description="description6" />
<Image select="2" readonly="false" />
</Name>
</Fix>
</Config>
XSLT1.0转换文件有三个相同的选择代码块用于Lock、React或Hold标记:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes" />
<xsl:variable name="updates" select="document('updates.xml')"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:variable name="name" select="name()"/>
<xsl:apply-templates select="$updates//*[name(.) = $name]/@*"/>
<xsl:apply-templates select="@*"/>
<xsl:choose>
<xsl:when test="self::node()[@Lock]">
<Lock const="{@Lock}">
<xsl:copy-of select="$updates//Lock/@*[name(.) != 'const']"/>
</Lock>
</xsl:when>
<xsl:otherwise>
<xsl:if test="($updates//*[name(.) = $name])[@Lock]">
<Lock>
<xsl:attribute name="const">
<xsl:value-of select="$updates//*[name(.) = $name]/@Lock"/>
</xsl:attribute>
<xsl:copy-of select="$updates//Lock/@*[name(.) != 'const']"/>
</Lock>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="self::node()[@React]">
<React const="{@React}">
<xsl:copy-of select="$updates//React/@*[name(.) != 'const']"/>
</React>
</xsl:when>
<xsl:otherwise>
<xsl:if test="($updates//*[name(.) = $name])[@React]">
<React>
<xsl:attribute name="const">
<xsl:value-of select="$updates//*[name(.) = $name]/@React"/>
</xsl:attribute>
<xsl:copy-of select="$updates//React/@*[name(.) != 'const']"/>
</React>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="self::node()[@Hold]">
<Hold const="{@Hold}">
<xsl:copy-of select="$updates//Hold/@*[name(.) != 'const']"/>
</Hold>
</xsl:when>
<xsl:otherwise>
<xsl:if test="($updates//*[name(.) = $name])[@Hold]">
<Hold>
<xsl:attribute name="const">
<xsl:value-of select="$updates//*[name(.) = $name]/@Hold"/>
</xsl:attribute>
<xsl:copy-of select="$updates//Hold/@*[name(.) != 'const']"/>
</Hold>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="@Lock" />
<xsl:template match="@React" />
<xsl:template match="@Hold" />
</xsl:stylesheet>
我如何将Lock, React或Hold标签的三个选择块转换为一个?
您可以参数化模板并调用它或应用模板(使用模式):
<xsl:template match="*">
<xsl:copy>
<xsl:variable name="name" select="name()"/>
<xsl:apply-templates select="$updates//*[name(.) = $name]/@*"/>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="." mode="compare">
<xsl:with-param name="att" select="'Lock'"/>
</xsl:apply-templates>
<xsl:apply-templates select="." mode="compare">
<xsl:with-param name="att" select="'React'"/>
</xsl:apply-templates>
<xsl:apply-templates select="." mode="compare">
<xsl:with-param name="att" select="'Hold'"/>
</xsl:apply-templates>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="compare">
<xsl:param name="att"/>
<xsl:variable name="name" select="name()"/>
<xsl:choose>
<xsl:when test="self::node()[@*[name() = $att]]">
<xsl:element name="{$att}">
<xsl:attribute name="const">
<xsl:value-of select="@*[name() = $att]"/>
</xsl:attribute>
<xsl:copy-of select="$updates//*[name() = $att]/@*[name(.) != 'const']"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:if test="($updates//*[name(.) = $name])[@*[name() = $att]]">
<Lock>
<xsl:attribute name="const">
<xsl:value-of select="$updates//*[name(.) = $name]/@*[name() = $att]"/>
</xsl:attribute>
<xsl:copy-of select="$updates//*[name() = $att]/@*[name(.) != 'const']"/>
</Lock>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
这样不一定会使代码变得更可读。