Reputation: 143
EDIT: The Example now contains all tags that are in my main document
Hello everyone! I just had a quick question about XSLT. I have a large xml file with many <DIMENSION_Id>
nodes nested inside each other. In each <DIMENSION_Id>
node there are two SYN tags: <SYN>String</SYN><SYN>Integer</SYN>
What I am trying to do is take the furthest child node of each DIMENSION_Id and connect it with all of its ancestor paths to create a URL.
i.e.
<DIMENSIONS VERSION="1.0.0">
<DIMENSION NAME="Category" SRC_TYPE="INTERNAL">
<DIMENSION_NODE ID="1000"/>
<DIMENSION_Id>
<SYN>Text</SYN>
<SYN>Number</SYN>
<DIMENSION_Id>
<SYN>More Text</SYN>
<SYN>Another Number</SYN>
</DIMENSION_Id>
</DIMENSION_Id>
</DIMENSION>
</DIMENSIONS>
I wrote this XSLT to get all information from the parent nodes first, then the child node last to create a full URL. Unfortunately it only gives me the information of the furthest child node...I do not know how to append any other text to it. (it should read something like: furthest-parent/closer-parent/parent/item_selected)
Unfortunately all it does is give me the value of the current node.... Here is the XSLT that I wrote:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/DIMENSION_NODE">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="@SYN" />
<xsl:text>/</xsl:text>
<xsl:value-of select="." />
<xsl:value-of select="@SYN" />
<xsl:text>/</xsl:text>
<xsl:value-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Thanks in advance for your help!
Upvotes: 1
Views: 183
Reputation: 143
Sorry for the confusion everyone. I received some help and here is the solution:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/">
<URLs>
<xsl:apply-templates select="//DIMENSION_NODE"/>
</URLs>
</xsl:template>
<xsl:template match="DIMENSION_NODE">
<xsl:call-template name="getPath">
<xsl:with-param name="currentnode" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="getPath">
<xsl:param name="currentnode"/>
<xsl:param name="currenttext" select="''"/>
<xsl:param name="firstrun" select="1"/>
<xsl:choose>
<xsl:when test="$currentnode[parent::DIMENSION]">
<URL>
<xsl:value-of select="$currenttext"/>
</URL>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$firstrun = 1">
<xsl:variable name="gettext">
<xsl:text>/</xsl:text>
<xsl:value-of select="concat($currentnode/DVAL/SYN[1],'	',$currentnode/DVAL/DVAL_ID/@ID)"/>
</xsl:variable>
<xsl:call-template name="getPath">
<xsl:with-param name="currentnode" select="$currentnode/.."/>
<xsl:with-param name="currenttext" select="concat($gettext,$currenttext)"/>
<xsl:with-param name="firstrun" select="0"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="gettext">
<xsl:text>/</xsl:text>
<xsl:value-of select="$currentnode/DVAL/SYN[1]"/>
</xsl:variable>
<xsl:call-template name="getPath">
<xsl:with-param name="currentnode" select="$currentnode/.."/>
<xsl:with-param name="currenttext" select="concat($gettext,$currenttext)"/>
<xsl:with-param name="firstrun" select="0"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Also I apologize for the mistakes in my XML file.
Upvotes: 0
Reputation:
EDIT: input sample more close to question.
With this input:
<DIMENSIONS VERSION="1.0.0">
<DIMENSION NAME="Category" SRC_TYPE="INTERNAL">
<DIMENSION_NODE ID="1000"/>
<DIMENSION_Id>
<SYN>Text</SYN>
<SYN>1</SYN>
<DIMENSION_Id>
<SYN>More Text</SYN>
<SYN>2</SYN>
</DIMENSION_Id>
</DIMENSION_Id>
</DIMENSION>
</DIMENSIONS>
Two options.
1) Applying templates to ancestor with mode:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()"/>
<xsl:template match="SYN[number()!=.]">
<xsl:apply-templates select="ancestor::DIMENSION_Id" mode="output"/>
<xsl:value-of select="concat(' ',../SYN[number()=.],'
')"/>
</xsl:template>
<xsl:template match="DIMENSION_Id" mode="output">
<xsl:value-of select="concat('/',SYN[number()!=.])"/>
</xsl:template>
</xsl:stylesheet>
2) With params:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="text()"/>
<xsl:template match="SYN[number()!=.]">
<xsl:param name="pPath"/>
<xsl:value-of select="concat($pPath,' ',../SYN[number()=.],'
')"/>
</xsl:template>
<xsl:template match="DIMENSION_Id">
<xsl:param name="pPath"/>
<xsl:apply-templates>
<xsl:with-param name="pPath"
select="concat($pPath,'/',SYN[number()!=.])"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Both output:
/Text 1
/Text/More Text 2
Upvotes: 1
Reputation: 243449
I guess that you want this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="DIMENSION_Id[not(DIMENSION_Id)]">
<xsl:apply-templates select="(.|ancestor::DIMENSION_Id)/SYN" mode="gen"/>
</xsl:template>
<xsl:template match="SYN" mode="gen">
<xsl:value-of select="concat('/',.)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when this transformation is applied on the provided XML document (corrected to be well-formed):
<DIMENSIONS VERSION="1.0.0">
<DIMENSION NAME="Category" SRC_TYPE="INTERNAL">
<DIMENSION_NODE ID="1000"/>
<DIMENSION_Id>
<SYN>Text</SYN>
<SYN>Number</SYN>
<DIMENSION_Id>
<SYN>More Text</SYN>
<SYN>Another Number</SYN>
</DIMENSION_Id>
</DIMENSION_Id>
</DIMENSION>
</DIMENSIONS>
the wanted, correct result is produced:
/Text/Number/More Text/Another Number
Upvotes: 1