My XML source specifies cross-references in linkGrp
. Based on those
cross-references specified by the @target attribute, I need to group the
values of the s
elements. If the target attribute contains one-to-one
reference, the code I have works well as follows:
<DIV>
<div id="e">
<s id="e1">AAAAA</s>
<s id="e2">BBBBB</s>
<s id="e3">CCCCC</s>
</div>
<div id="fr">
<s id="fr1">DDDDD</s>
<s id="fr2">EEEEE</s>
<s id="fr3">FFFFF</s>
</div>
<linkGrp type="alignment" domains="e fr">
<link target="#e1 #fr1"/>
<link target="#e2 #fr3"/>
<link target="#e3 #fr2"/>
</linkGrp>
</DIV>
The requested HTML output I get is this:
*AAAAA
DDDDD
*BBBBB
FFFFF
*CCCCC
EEEEE
To get this result I use the following XSLT code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="linkId" match="s" use="@id"/>
<xsl:template match="/DIV">
<html>
<head>
<title>Test</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="link">
<ul>
<li>
<xsl:value-of select="key('linkId',substring-before(substring-after(@target, '#'), ' '))"/>
<br/>
<xsl:value-of select="key('linkId',substring-after(@target, ' #'))"/>
</li>
</ul>
</xsl:template>
<xsl:template match="div"/>
<xsl:template match="s"/>
<xsl:template match="*">
<xsl:message terminate="no">
WARNING: Unmatched element: <xsl:value-of select="name()"/>
</xsl:message>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
However, my XSLT code does not work that well when I add more cross-references for one @target in the link
elements as this:
<DIV>
<div id="e">
<s id="e1">AAAAA</s>
<s id="e2">BBBBB</s>
<s id="e3">CCCCC</s>
</div>
<div id="fr">
<s id="fr1">DDDDD</s>
<s id="fr2">EEEEE</s>
<s id="fr3">FFFFF</s>
</div>
<linkGrp type="alignment" domains="e fr">
<link target="#e1 #fr1"/>
<link target="#e2 #fr3 #fr1 #fr2"/>
<link target="#e3 #fr2 #fr3"/>
</linkGrp>
</DIV>
With multiple cross-references in the XML source, my XSLT code does not fetch
any match. And I need my code to retrieve all matches specified in the @target
attribute. Can anyone point the mistake in my XSLT code or offer alternative
solution?
With xslt-1.0 you may use a recursive template call to split up the ids. Try something like this:
Which will generate the following output:
An alternative solution may be to use the xpath function
id()
. But to make it work your XML need to have a DTD DOCTYPE. Something like this:With this XML your link template could be change as following: