我们如何根据xslt中的某些条件创建属性。
我的输入xml有一个标记:
<track external="http://mysite.com" />
or
<track local="/myfolder" />
并在这个'track元素中出现外部或本地属性但不是这些中的任何一个,我必须将其转换为
<a xhtml:href="@external value" xmlns="http://www.w3.org/1999/xhtml" />
如果'track'元素出现'extrenal'属性或进入
<a xlink:href="@local value" xmlns="http://www.w3.org/1999/xlink" />
如果'track'元素出现'local'属性
XSLT尝试过:
<a xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:for-each select="child::*" >
<xsl:choose>
<xsl:when test="name()='track'">
<xsl:if test="@local">
<xsl:attribute name="xlink:href">
<xsl:value-of select="@local" />
</xsl:attribute>
</xsl:if>
<xsl:if test="@external">
<xsl:attribute name="xhtml:href">
<xsl:value-of select="@external" />
</xsl:attribute>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</a>
但抛出异常,因为我根据条件创建了'a'元素的属性。这在XSLT 1.0中是不被接受的,是否有任何方法可以根据XSLT 1.0中的某些条件为我的'a'元素显示属性。
答案 0 :(得分:3)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:mappings>
<map from="external" to="xhtml"/>
<map from="local" to="xlink"/>
</my:mappings>
<xsl:variable name="vMaps" select="document('')/*/my:mappings/*"/>
<xsl:variable name="vNamespaces" select="document('')/*/namespace::*"/>
<xsl:template match="/*">
<t><xsl:apply-templates/></t>
</xsl:template>
<xsl:template match="track">
<xsl:element name="a"
namespace="{$vNamespaces[name()=$vMaps[@from=name(current()/@*)]/@to]}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{$vMaps[@from=name(current())]/@to}:href"
namespace="{$vNamespaces[name()=$vMaps[@from=name(current())]/@to]}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<t>
<track external="http://mysite.com" />
<track local="/myfolder" />
</t>
会产生想要的正确结果:
<t xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<a xmlns="http://www.w3.org/1999/xhtml" xhtml:href="http://mysite.com"/>
<a xmlns="http://www.w3.org/1999/xlink" xlink:href="/myfolder"/>
</t>
请注意此解决方案具有一些独特的功能,例如:
没有使用条件指令,因此代码更简单,更不容易出错。
使用纯粹的“推”式。
产生了确切的想要结果。
答案 1 :(得分:1)
没有什么能阻止您在XSLT 1.0中有条件地添加属性。顺便说一句,避免在XSLT中使用for-each而是使用模板。这是track
节点的专用模板。
<xsl:template match='track'>
<a xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:if test="@local">
<xsl:attribute name="xlink:href">
<xsl:value-of select="@local" />
</xsl:attribute>
</xsl:if>
<xsl:if test="@external">
<xsl:attribute name="xhtml:href">
<xsl:value-of select="@external" />
</xsl:attribute>
</xsl:if>
</a>
</xsl:template>
正如Tim C所提到的,更好的模式是通过不同的模板处理不同类型的传入属性。尽管如此,这个更干净,因为你不会陷入条件障碍。
<xsl:template match='track'>
<a><xsl:apply-templates select='@*' /></a>
</xsl:template>
<xsl:template match='@local' xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:attribute name="xlink:href">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match='@external' xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xsl:attribute name="xhtml:href">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
您可以在this XMLPlayground中看到这两种方法。
答案 2 :(得分:1)
您应该使用模板匹配来匹配相关情况。首先,不要使用 xsl:for-each ,而是使用 xsl:apply-templates
<xsl:apply-templates select="*" />
然后有单独的模板来匹配是否存在本地或外部属性
<xsl:template match="track[@external]">
<a xhtml:href="{@external}" />
</xsl:template>
<xsl:template match="track[@local]">
<a xlink:href="{@local}" />
</xsl:template>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="album">
<p>
<xsl:apply-templates select="*" />
</p>
</xsl:template>
<xsl:template match="track[@external]">
<a xhtml:href="{@external}" />
</xsl:template>
<xsl:template match="track[@local]">
<a xlink:href="{@local}" />
</xsl:template>
</xsl:stylesheet>
应用于以下XSLT
时<album>
<track external="http://mysite.com"/>
<track local="/myfolder"/>
</album>
以下是输出
<p xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/">
<a xhtml:href="http://mysite.com" />
<a xlink:href="/myfolder" />
</p>