I have input data:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
<objects>
<object>
<properties>
<property>
<label>This is a label. Label contains <reference ref="#">references</reference> in random <reference ref="#">places</reference></label>
</property>
</properties>
</object>
<object/>
</objects>
and transformation file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="1.0" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="//objects/object">
<xsl:for-each select="properties/property">
<xsl:value-of select="label"/>
<xsl:for-each select="label/reference">
<a href="{@ref}"><xsl:value-of select="."/></a>
</xsl:for-each>
<br/>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Expected result is:
This is a label. Label contains references in random places
but I'm getting:
This is a label. Label contains references in random places references places
How to solve that issue?
In your for-each
iterating over properties/property
you are outputting the reference-elements after the label-text-node. Instead iterate over all node()'s and choose between node-types:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="1.0" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:element name="html">
<xsl:element name="body">
<xsl:for-each select="//objects/object">
<xsl:for-each select="properties/property">
<xsl:for-each select="label/node()">
<xsl:choose>
<xsl:when test="self::text()">
<xsl:value-of select="." />
</xsl:when>
<xsl:when test="local-name() = 'reference'">
<a href="{@ref}"><xsl:value-of select="." /></a>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<xsl:element name="br" />
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This is a classic case where you should be using template rules rather than for-each. Replace your outermost for-each with <xsl:apply-templates select="//objects"/>
and then do
<xsl:template match="label/reference">
<a href="{@ref}"><xsl:value-of select="."/></a>
</xsl:template>
That's all you need: everything else is taken care of by the default template rules.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.