Subject: [xsl] Grouping hierarchy path elements, part 2 From: "Daniel Geske" <Daniel.Geske@xxxxxx> Date: Tue, 24 Aug 2004 10:58:20 +0200 |
Hi all, I am a great deal further now, since I can re-create the tree structure from a path string. Now again, my task has become a bit more complicated. Instead of extracting the path of an element right from the source document root, references to elements containing the path information are grouped in other elements. Elements containing paths are to be transformed into the destination document selectively. To make things clearer, here is an example of the source file: <?xml version="1.0" encoding="UTF-8"?> <sourceDocument> <items> <item id="1"> <path>root\folderA\folderB\folderC</path> </item> <item id="2"> <path>root\folderA\folderB\folderD</path> </item> <item id="3"> <path>root\folderA\folderE\folderF</path> </item> <item id="4"> <path>root\folderG</path> </item> <item id="5"> <path>root\folderA\folderB\folderD</path> </item> </items> <otherItems> <otherItem id="A"> <referenceItemId>2</referenceItemId> <referenceItemId>3</referenceItemId> <referenceItemId>5</referenceItemId> </otherItem> <otherItem id="B"> <referenceItemId>5</referenceItemId> </otherItem> </otherItems> </sourceDocument> This is what the transformed file should look like: <?xml version="1.0" encoding="UTF-8"?> <transformedDocument> <Chapter id="A"> <path name="root"> <path name="folderA"> <path name="folderB"> <path name="folderD"> <item id="2" /> <item id="5" /> </path> </path> <path name="folderE"> <path name="folderF"> <item id="3" /> </path> </path> </path> </path> </Chapter> <Chapter id="B"> <path name="root"> <path name="folderA"> <path name="folderB"> <path name="folderD"> <item id="5" /> </path> </path> </path> </path> </Chapter> </transformedDocument> My current XSLT looks like this: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl=" http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/> <!-- Match the source document root --> <xsl:template match="/sourceDocument"> <transformedDocument> <xsl:apply-templates select="otherItems"/> <!-- Uncomment line below to check wheather template items is working. --> <!--xsl:apply-templates select="items"/--> </transformedDocument> </xsl:template> <xsl:template match="otherItems"> <xsl:apply-templates/> </xsl:template> <xsl:template match="otherItem"> <!-- Create a node 'Chapter' for each element 'otherItem'. --> <Chapter> <xsl:attribute name="id"><xsl:value-of select="attribute::id"/></ xsl:attribute> <xsl:variable name="root" select=" substring-before(//items/item[1]/path, '\')"/> <path name="{$root}"> <xsl:call-template name="transformDocument"> <xsl:with-param name="path" select="$root"/> <xsl:with-param name="items" select=" //item[attribute::id=referenceItemId]"/> </xsl:call-template> </path> <xsl:comment> <xsl:text>//item[attribute::id]: </xsl:text> <xsl:value-of select="//item[attribute::id]"/> <xsl:text> </xsl:text> <xsl:text>referenceItemId: </xsl:text> <xsl:value-of select="referenceItemId"/> </xsl:comment> </Chapter> </xsl:template> <xsl:template match="items"> <xsl:variable name="root" select="substring-before(item[1]/path, '\') "/> <path name="{$root}"> <xsl:call-template name="transformDocument"> <xsl:with-param name="path" select="$root"/> <xsl:with-param name="items" select="item"/> </xsl:call-template> </path> </xsl:template> <xsl:template name="transformDocument"> <xsl:param name="path"/> <xsl:param name="items" select="$items"/> <xsl:comment> <xsl:text>transformDocument called with items param='</xsl:text> <xsl:value-of select="$items"/> <xsl:text>'</xsl:text> </xsl:comment> <xsl:if test="$items"> <xsl:variable name="step"> <xsl:variable name="rest" select="substring-after($items[1]/path, concat($path, '\'))"/> <xsl:choose> <xsl:when test="contains($rest, '\')"> <xsl:value-of select="substring-before($rest, '\')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$rest"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="newPath" select="concat($path, '\', $step)"/> <path name="{$step}"> <xsl:apply-templates select="$items[path = $newPath]"/> <xsl:call-template name="transformDocument"> <xsl:with-param name="path" select="$newPath"/> <xsl:with-param name="items" select="$items[starts-with(path, concat($newPath, '\'))]"/> </xsl:call-template> </path> <xsl:call-template name="transformDocument"> <xsl:with-param name="path" select="$path"/> <xsl:with-param name="items" select="$items[path != $newPath and not(starts-with(path, concat($newPath, '\')))]"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template match="item"> <xsl:comment> <xsl:text>Item path=</xsl:text> <xsl:value-of select="path"/> </xsl:comment> <item id="{@id}"/> </xsl:template> </xsl:stylesheet> It seems as if there is something wrong with my items parameter for the transformDocument template called from the template 'otherItem'. If you run the above, you will notice that <xsl:value-of select=" //item[attribute::id]"/> actually does not return the id-Attribute element of all items, but instead returns the child elements of the first referenced item. Finding a solution to this would get me a big step ahead I think. Maybe anybody could point me the right direction? Thanks a lot. Mit freundlichen Gr|_en / Sincerely Daniel Geske Telematik/Infotainment, AE-V32 Telematics/Infotainment, AE-V32 IAV GmbH Ingenieurgesellschaft Auto und Verkehr Carnotstra_e 1 10587 Berlin Germany Tel.: +49 (30) 3 99 78 - 90 44 Fax: +49 (30) 3 99 78 - 94 11 E-mail: <mailto:daniel.geske@xxxxxx> Internet: http://www.iav.de
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Printing a value if an at, Vasu Chakkera | Thread | Re: [xsl] Grouping hierarchy path e, Jeni Tennison |
Re: [xsl] Best practices - using va, David Carlisle | Date | Re: [xsl] Grouping hierarchy path e, Jeni Tennison |
Month |