Subject: import Walker From: "Benoit Cerrina" <benoit.cerrina@xxxxxxxxxxx> Date: Mon, 23 Oct 2000 20:18:38 +0200 |
Hi (this is my third posting, I hope it will get through), here is my problem: I have some xml documents with the equivalent of an import clause in java, essentially it could look like this ----doc a----------- <?xml version="1.0" encoding="UTF-8"?> <doc name="a"> <import name="b"/> <import name="c"/> <object id="1" ref="2" payload="A"/> </doc> ----end doc a----------- ----doc b----------- <?xml version="1.0" encoding="UTF-8"?> <doc name="b"> <import name="a"/> <object id="2" ref="3" payload="B"/> <object id="3" payload="C"/> </doc> ----end doc b----------- ----doc c----------- <?xml version="1.0" encoding="UTF-8"?> <doc name="c"> <import name="b"/> </doc> ----end doc c----------- So we have an import tree which looks like: a---->b---->a |---->c---->b---->a Now I'm processing the document "a" I'd like to get: <object id=1> ABC </object> or in english each time I encounter an object I need to print out it's payload and the payload of its reference and its reference's reference... My problem is that I know how to do a depth first transversal of the import graph of document, I even know how to avoid problems with the cycle which appears due to the import of a in b, however I don't know how to deal with the fact that both branches have a part in common. This is actually the same problem as with multiinheritance in c++ and the losange pattern. All my efforts have yielded the following result: <object id=1> ABCBC </object> Benoit PS: this is what my stylesheet looks like: ------importWalker.xsl------- <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <!--main template--> <xsl:template match="doc"> <xsl:apply-templates select="object"/> </xsl:template> <xsl:template match="object"> <object id="{@id}"> <xsl:apply-templates select="." mode="payload"/> </object> </xsl:template> <xsl:template match="object" mode="payload"> <!--passthrough parameter to the walker--> <xsl:param name="visitedDocs" select="/.."/> <xsl:value-of select="@payload"/> <xsl:if test="@ref"> <xsl:call-template name="importWalker"> <xsl:with-param name="visitedDocs" select="$visitedDocs"/> <xsl:with-param name="target" select="@ref"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name="importWalker"> <xsl:param name="visitedDocs" select="/.."/> <xsl:param name="target"/> <xsl:variable name="newVisitedDocs" select="$visitedDocs | /doc/@name"/> <xsl:variable name="targetObj" select="//object[@id = $target]"/> <xsl:choose> <!--first test if the object is in this document I know // is ugly in truth I use key--> <xsl:when test="$targetObj"> <!--found it print payloads and recurse--> <xsl:apply-templates select="$targetObj" mode="payload"> <xsl:with-param name="visitedDocs" select="$newVisitedDocs"/> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <!--iterate and recurse other all imports--> <xsl:for-each select="document(/doc/import/@name, .)"> <!--check for import cycles--> <xsl:variable name="docName" select="/doc/@name"/> <xsl:if test="not($newVisitedDocs[string(.) = string($docName)])"> <xsl:call-template name="importWalker"> <xsl:with-param name="target" select="$target"/> <xsl:with-param name="visitedDocs" select="$newVisitedDocs"/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> ------end importWalker.xsl------- XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: A very simple question, Miloslav Nic | Thread | selection problem in mixed-content, Richard Lander |
A very simple question, Adenilson Roberto Ca | Date | selection problem in mixed-content, Richard Lander |
Month |