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

Collecting attributes from the ancestor-or-self axis

Subject: Collecting attributes from the ancestor-or-self axis
From: "B. Tommie Usdin" <btusdin@xxxxxxxxxxxxxxxx>
Date: Fri, 16 Nov 2001 09:36:39 -0500
ancestor or self attribute
>From: "WATKIN-JONES,ADAM (HP-UnitedKingdom,ex1)" <adam_watkin-jones@xxxxxx>
>To: "'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
>Subject: Help collecting attributes from the ancestor-or-self axis
>Date: Fri, 16 Nov 2001 14:22:50 -0000
>Hello!
>
>I am trying to write some XSLT to do the following:
>
>1. start at element E
>2. add all its attributes to the output
>3. move to E's parent, EP
>4. add to the output all those attributes
>   of EP that do not have the same name as
>   as an attribute already added to the output
>5. move to EP's parent and so on collecting
>   new attributes until I've reached the last
>   ancestor of P.
>
>Below is some XML input, XML output and XSLT.
>(Actually there's a second XSLT at the end as well.)
>
>The XSLT processes the input as intended but I'm not very satisfied with it
>- it feels a bit cludgy and I'm concerned it will perform poorly on a big
>input document.
>
>Question 1
>
>The second XSLT represents an attempt to improve on the first.  The problem
>is that it requires a mysterious ingredient, possessed by very few (all
>right then, maybe possessed by many but not by me!): ?something magical?.
>
>?something magical? is some XPath that takes a node set of attributes and an
>element and it should find all the attributes of the element that do not
>have the same name as an attribute in the node set.
>
>Question 2
>Have I got the basic technique wrong?  Is there some more powerful magic out
>there?  (I tried to use the ancestor-or-self axis to construct a node set of
>all attributes of interest and then turn it into some sort of grouping
>problem but couldn't figure out how to make it work.)
>
>
>Many thanks!
>
>Adam
>
>
>
>/////////////////////////////////////////////////////////////////
>/// XML
>
><?xml version="1.0"?>
>
><elem1
>        attr0="a"
>        attr1="b"
>        attr2="c"
>        attr3="d">
>    <elem2
>            attr1="e"
>            attr3="f"
>            attr4="g"
>            attr5="h"
>            attr6="i">
>        <elem3
>                attr1="j"
>                attr2="k"
>                attr7="l"
>                attr8="m"
>                attr9="n"/>
>    </elem2>
></elem1>
>
>
>/////////////////////////////////////////////////////////////////
>/// OUTPUT (Saxon 6.4.3)
>
><?xml version="1.0" encoding="utf-8"?>
><attributes>
>   <attribute name="attr1" value="j" context="elem3"/>
>   <attribute name="attr2" value="k" context="elem3"/>
>   <attribute name="attr7" value="l" context="elem3"/>
>   <attribute name="attr8" value="m" context="elem3"/>
>   <attribute name="attr9" value="n" context="elem3"/>
>   <attribute name="attr3" value="f" context="elem2"/>
>   <attribute name="attr4" value="g" context="elem2"/>
>   <attribute name="attr5" value="h" context="elem2"/>
>   <attribute name="attr6" value="i" context="elem2"/>
>   <attribute name="attr0" value="a" context="elem1"/>
></attributes>
>
>
>/////////////////////////////////////////////////////////////////
>/// XSLT
>
><?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"/>
>
>
>    <xsl:template match="/">
>        <attributes>
>            <xsl:call-template name="GetAttributes">
>                <xsl:with-param name="nsAttributes" select="/.."/>
>                <xsl:with-param name="nsContext"
>select="elem1/elem2/elem3"/>
>            </xsl:call-template>
>        </attributes>
>    </xsl:template>
>
>
>    <xsl:template name="GetAttributes">
>
>        <xsl:param name="nsAttributes"/>
>        <xsl:param name="nsContext"/>
>
>        <xsl:variable name="nsNewAttributes">
>            <dummy>
>                <xsl:for-each select="$nsContext/attribute::*">
>                    <xsl:if test="count($nsAttributes/dummy/attribute/
>                            @name[. = name(current())]) = 0">
>                        <attribute name="{name()}"/>
>                    </xsl:if>
>                </xsl:for-each>
>            </dummy>
>        </xsl:variable>
>
>        <xsl:variable name="nsParent" select="$nsContext/.."/>
>
>        <xsl:for-each select="$nsContext/attribute::*">
>            <xsl:if test="0 = count($nsAttributes/dummy/attribute/
>                    @name[. = name(current())])">
>                <attribute name="{name()}" value="{.}"
>                        context="{name($nsContext)}"/>
>            </xsl:if>
>        </xsl:for-each>
>
>        <xsl:if test="$nsParent">
>            <xsl:call-template name="GetAttributes">
>                <xsl:with-param name="nsAttributes"
>                        select="$nsAttributes | $nsNewAttributes"/>
>                <xsl:with-param name="nsContext" select="$nsParent"/>
>            </xsl:call-template>
>        </xsl:if>
>
>    </xsl:template>
>
>
></xsl:stylesheet>
>
>
>/////////////////////////////////////////////////////////////////
>/// XSLT Preferred (just requires ?something magical?)
>
><?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"/>
>
>
>    <xsl:template match="/">
>        <attributes>
>            <xsl:call-template name="GetAttributes">
>                <xsl:with-param name="nsAttributes" select="/.."/>
>                <xsl:with-param name="nsContext"
>select="elem1/elem2/elem3"/>
>            </xsl:call-template>
>        </attributes>
>    </xsl:template>
>
>
>    <xsl:template name="GetAttributes">
>
>        <xsl:param name="nsAttributes"/>
>        <xsl:param name="nsContext"/>
>
>        <xsl:variable name="nsNewAttributes" select="?something magical?">
>
>        <xsl:variable name="nsParent" select="$nsContext/.."/>
>
>        <xsl:for-each select="$nsNewAttributes">
>            <attribute name="{name()}" value="{.}"
>                    context="{name($nsContext)}"/>
>        </xsl:for-each>
>
>        <xsl:if test="$nsParent">
>            <xsl:call-template name="GetAttributes">
>                <xsl:with-param name="nsAttributes"
>                        select="$nsAttributes | $nsNewAttributes"/>
>                <xsl:with-param name="nsContext" select="$nsParent"/>
>            </xsl:call-template>
>        </xsl:if>
>
>    </xsl:template>
>
>
></xsl:stylesheet>



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.