[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Querying Result Tree

Subject: Re: Querying Result Tree
From: David Carver <d_a_carver@xxxxxxxxx>
Date: Thu, 22 Dec 2005 10:45:58 -0500
oagis 9
What I want to do is make sure that I don't add a duplicate node to the result document, when an earlier template may have already added the result.

The word "earlier" gives away that you're thinking procedurally. XSLT is a
functional language, the output has to be expressed as a function of the
input, not as a function of things that happened "earlier", because there is
no defined order of execution.

If you can't express the logic as a function of the original input, then use
a multi-phase transformation.


Michael,

Here is what I'm trying to do. I have a W3C Schemas that has multiple includes and imports. What I would like to do is take a given Schemas, and include in an output schemas all of the components that used by that schemas in a flattened schemas. The only included items should be those that are used.

This is what the Schemas could look like:

Schemas 1
    Includes complexTypes and elements from Schemas 2
           Includes complexTypes and elements from Schmeas 3
           Includes complexTypes and elements from schemas 4

I've got it pretty much working, the only big issue I'm having is that some of the ComplexTypes tend to re-occur, and I only want to include them if they haven't already occured. The issue happens when they are nested in an unlimited fashion.

ComplexType 1 may include ComplexType2 which may include ComplexType 3 which may include ComplexType1 again.

Yeah, I know horrible and ugly, but until we can get it redesigned, it's what I'm dealing with. What eventually happens is that the various XSLT processors fail because of too many applys. It basically gets in an infinete loop.


XSLT:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:param name="fieldsLocation">file:///D:/Work/OAGIS90POC/Development/STAR/Rev/Resources/Components/Common/NewFields90.xsd</xsl:param>
<xsl:param name="metaLocation">file:///D:/Work/OaGIS90POC/Development/STAR/Rev/Resources/Components/Common/Meta.xsd</xsl:param>
<xsl:param name="componentsLocation">file:///D:/Work/OAGIS90POC/Development/STAR/Rev/Resources/Components/Common/NewComponents90.xsd</xsl:param>
<xsl:variable name="nounLocation">file:///D:/Work/OAGIS90POC/Development/STAR/Rev/Resources/Noun90/RepairOrder.xsd</xsl:variable>
<!-- Process the Root -->
<xsl:template match="xsd:schema">
<xsl:variable name="resultDoc">
<xsl:variable name="currentDoc" select="xsd:element | xsd:complexType | document($nounLocation)/xsd:schema/xsd:element | document($nounLocation)/xsd:schema/xsd:complexType"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsd:import namespace="http://www.starstandards.org/STAR/5/unqualifieddatatypes/1.0" schemaLocation="../../Resources/Components/Common/UnqualifiedDataTypes.xsd"/>
<xsd:import namespace="http://www.starstandards.org/STAR/5/qualifieddatatypes/1.0" schemaLocation="../../Resources/Components/Common/QualifiedDataTypes.xsd"/>
<xsd:import namespace="http://www.starstandards.org/STAR/5/codelists" schemaLocation="../../Resources/Components/Common/CodeLists.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/qualifieddatatypes/1.1" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/QualifiedDataTypes.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/unqualifieddatatypes/1.1" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/UnqualifiedDataTypes.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/codelists" schemaLocation="../../Resources/Components/OAGIS/Common/CodeLists.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/currencycode/54217:2001" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/CodeList_CurrencyCode_ISO_7_04.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/languagecode/5639:1988" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/CodeList_LanguageCode_ISO_7_04.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/IANAMIMEMediaTypes:2003" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/CodeList_MIMEMediaTypeCode_IANA_7_04.xsd"/>
<xsd:import namespace="http://www.openapplications.org/oagis/9/unitcode/66411:2001" schemaLocation="../../Resources/Components/OAGIS/CoreComponents/CodeList_UnitCode_UNECE_7_04.xsd"/>
<xsl:copy-of select="xsd:element"/>
<!-- Process the main schemas elements and any of the result tree elements that have been created -->
<xsl:apply-templates select="xsd:element | xsd:complexType | $currentDoc//xsd:element[@ref != '']"/>
</xsl:copy>
</xsl:variable>
<!-- clean up the final result befor outputting -->
<xsl:apply-templates select="$resultDoc/xsd:schema" mode="RemoveDups"/> </xsl:template>


<xsl:template match="xsd:schema" mode="RemoveDups">
<xsl:variable name="elementsSorted">
<xsl:for-each select="xsd:element">
<xsl:sort select="@name"/>
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="complexTypesSorted">
<xsl:for-each select="xsd:complexType">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="xsd:include | xsd:import">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:for-each>
<xsl:for-each select="$elementsSorted/xsd:element[not(following-sibling::*/@name = @name)]">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:for-each>
<xsl:for-each select="$complexTypesSorted/xsd:complexType[not(following-sibling::*/@name = @name)]">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- Process an element, and look for it's definition in one of the potential included files
if found, then copy that element definition in, an look for the the ComplexType defined by
the type attribute of the element
-->
<xsl:template match="xsd:element">
<xsl:variable name="elementName" select="@ref | @name"/>
<xsl:variable name="copyFieldMeta" select="document($metaLocation)/xsd:schema/xsd:element[@name = $elementName]"/>
<xsl:variable name="copyFieldField" select="document($fieldsLocation)/xsd:schema/xsd:element[@name = $elementName]"/>
<xsl:variable name="copyFieldComponent" select="document($componentsLocation)/xsd:schema/xsd:element[@name = $elementName]"/>
<xsl:variable name="copyFieldNoun" select="document($nounLocation)/xsd:schema/xsd:element[@name = $elementName]"/>
<xsl:choose>
<xsl:when test="$copyFieldField">
<xsl:copy-of select="$copyFieldField" copy-namespaces="no"/>
<xsl:apply-templates select="document($componentsLocation)/xsd:schema/xsd:complexType[@name = $copyFieldField/@type] | document($metaLocation)/xsd:schema/xsd:complexType[@name = $copyFieldField/@type]"/>
</xsl:when>
<xsl:when test="$copyFieldComponent">
<xsl:copy-of select="$copyFieldComponent" copy-namespaces="no"/>
<xsl:apply-templates select="document($componentsLocation)/xsd:schema/xsd:complexType[@name = $copyFieldComponent/@type] | document($metaLocation)/xsd:schema/xsd:complexType[@name = $copyFieldComponent/@type]"/>
</xsl:when>
<xsl:when test="$copyFieldMeta">
<xsl:copy-of select="$copyFieldMeta" copy-namespaces="no"/>
<xsl:apply-templates select="document($componentsLocation)/xsd:schema/xsd:complexType[@name = $copyFieldMeta/@type] | document($metaLocation)/xsd:schema/xsd:complexType[@name = $copyFieldMeta/@type]"/>
</xsl:when>
<xsl:when test="$copyFieldNoun">
<xsl:copy-of select="$copyFieldNoun" copy-namespaces="no"/>
<xsl:apply-templates select="document($nounLocation)/xsd:schema/xsd:complexType[@name = $copyFieldNoun/@type] | document($metaLocation)/xsd:schema/xsd:complexType[@name = $copyFieldNoun/@type] | document($componentsLocation)/xsd:schema/xsd:complexType[@name = $copyFieldNoun/@type]"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- Copy a found ComplexType into the result tree -->
<!-- Note this is where the infinite loop can occur -->
<!-- the code that checks for the name not equal to ref name works unless
the ref's name is not the same -->
<xsl:template match="xsd:complexType">
<xsl:variable name="complexName" select="substring-before(@name, 'Type')"/>
<xsl:copy-of select="." copy-namespaces="no"/>
<xsl:if test="descendant::xsd:extension">
<xsl:variable name="baseName" select="descendant::xsd:extension/@base"/>
<xsl:apply-templates select="document($componentsLocation)/xsd:schema/xsd:complexType[@name = $baseName] | document($metaLocation)/xsd:schema/xsd:complexType[@name = $baseName] | document($nounLocation)/xsd:schema/xsd:complexType[@name = $baseName]"/>
</xsl:if>
<xsl:apply-templates select="descendant::xsd:element[not(@ref = $complexName)]"/>
</xsl:template>
</xsl:stylesheet>



Any suggestions or ideas on how to avoid the recursion would be appreciated.


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.