使用xslt将字符串以分号分隔为xml元素
我已经转换了xml:使用xslt将字符串以分号分隔为xml元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我已经转换了xml: <import> <issue> <article> <languageVersion> <title>some title</title> <keywords>keyword1; keyword2; keyword3</keywords> &l
<import>
<issue>
<article>
<languageVersion>
<title>some title</title>
<keywords>keyword1; keyword2; keyword3</keywords>
</languageVersion>
</article>
<article>
<languageVersion>
<title>some title</title>
<keywords>keyword1; keyword2; keyword3</keywords>
</languageVersion>
</article>
</issue>
</import>
但不幸的是,代码正在破坏其余的xml元素:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="keywords">
<keywords>
<xsl:apply-templates/>
</keywords>
</xsl:template>
<xsl:template match="keywords" name="split">
<xsl:param name="pText" select="."/>
<xsl:param name="pItemElementName" select="'keyword'"/>
<xsl:if test="string-length($pText) > 0">
<xsl:variable name="vNextItem" select=
"substring-before(concat($pText, ';'), ';')"/>
<xsl:element name="{$pItemElementName}">
<xsl:value-of select="$vNextItem"/>
</xsl:element>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ';')"/>
<xsl:with-param name="pItemElementName" select="$pItemElementName"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
您有两个模板匹配关键字
,如果它们具有相同的优先级,则在XSLT中被视为错误。根据规范
XSLT处理器可能会发出错误信号;如果它没有发出信号
错误,必须从匹配模板中选择恢复
剩下的规则,即样式表中最后出现的规则
因此,在您的例子中,只使用了第二个模板
但是,您只需删除第二个模板上的“匹配项”,使其成为命名模板,然后更改第一个模板以直接调用命名模板。您还应该添加标识模板,以处理现有元素,然后您的工作就完成了
试试这个XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="keywords">
<xsl:copy>
<xsl:call-template name="split" />
</xsl:copy>
</xsl:template>
<xsl:template name="split">
<xsl:param name="pText" select="."/>
<xsl:param name="pItemElementName" select="'keyword'"/>
<xsl:if test="string-length($pText) > 0">
<xsl:variable name="vNextItem" select=
"substring-before(concat($pText, ';'), ';')"/>
<xsl:element name="{$pItemElementName}">
<xsl:value-of select="$vNextItem"/>
</xsl:element>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ';')"/>
<xsl:with-param name="pItemElementName" select="$pItemElementName"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这几乎完美无瑕,但它并不是在元素之间创建节点,我应该做些什么来获得它?我已经修改了我的答案来做到这一点。现在效果非常好,我批准了答案。除此之外,还可以从所有关键字中删除空格?因此,它将取代关键字2。是的,您可以使用规范化空间
函数,因此您将执行
是的,这就是我所说的。谢谢
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="keywords">
<xsl:copy>
<xsl:call-template name="split" />
</xsl:copy>
</xsl:template>
<xsl:template name="split">
<xsl:param name="pText" select="."/>
<xsl:param name="pItemElementName" select="'keyword'"/>
<xsl:if test="string-length($pText) > 0">
<xsl:variable name="vNextItem" select=
"substring-before(concat($pText, ';'), ';')"/>
<xsl:element name="{$pItemElementName}">
<xsl:value-of select="$vNextItem"/>
</xsl:element>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ';')"/>
<xsl:with-param name="pItemElementName" select="$pItemElementName"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>