XSL Transform Help Please

Discussion in 'XML' started by Candle, Dec 8, 2006.

  1. Candle

    Candle Guest

    I am having a problem with writing an XSL Transform. Please help.

    Note: I know this a long post but I wanted to provide as must detail as
    possible. Any help would be appreciated. (Just started writing my
    first transform yesterday and no one at my company knows this stuff.)

    Assume I have the following XML:

    <P C="P" O="1" >
    <E C="P_E1" O="1" W='True'>
    <A C="P_E1A1" V="1" />
    <A C="P_E1A1" V="2" />
    </E>
    <E C="P_E10" O="13" W='True'>
    <A C="P_E10A1" V="25" />
    <A C="P_E10A1" V="26" />
    <E C="P_E10E1" O="13_1" W='True'>
    <A C="P_E10E1A1" V="25_1" />
    <A C="P_E10E1A1" V="26_1" />
    <E C="P_E10E1E1" O="13_1_1" W='True'>
    <A C="P_E10E1E1A1" V="25_1_1" />
    <A C="P_E10E1E1A1" V="26_1_1" />
    </E>
    </E>
    </E>
    <E C="P_E11" O="13" >
    <A C="P_E11A1" V="25" />
    <A C="P_E11A1" V="26" />
    <E C="P_E11E1" O="13_1" W='True'>
    <A C="P_E11E1A1" V="25_1" />
    <A C="P_E11E1A1" V="26_1" />
    <E C="P_E11E1E1" O="13_1_1" W='True'>
    <A C="P_E11E1E1A1" V="25_1_1" />
    <A C="P_E11E1E1A1" V="26_1_1" />
    </E>
    </E>
    </E>
    <E C="P_E12" O="14" >
    <A C="P_E12A1" V="27" />
    <E C="P_E12E1" O="15" W='True'>
    <A C="P_E12E1A1" V="27_1" />
    </E>
    </E>
    </P>

    High-level Requirements:
    Basically, I need to get all of the nodes where the attribute
    W='True". These nodes need to be grouped together with the parent
    element tag, plus attributes, that does not have a W attribute.

    More Detail:
    I need to merge this information into an existing system.
    The W="True" indicates that the Entity (E) is a new element.
    If an Entity (E) has an attribute of W="True" all child Entities
    (E) will also have a W="True". (If the parent is new, all children,
    grandchildren and etc are new as well.)
    I need the parent element to reference the exiting item to merge in all
    of the new Entities.

    Here is what I have so far:

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput method="xml" encoding="UTF-8" />
    <xsl:template match="/">
    <root>
    <!-- Get IsNew Entities Plus Parent-->
    <IsNewPlusParent>

    <!-- Get all entities which are new plus thier parents -->
    <xsl:apply-templates select="//P [E[@W='True']] | //E
    [E[@W='True']]" mode="IsNewPlusParent"/>

    </IsNewPlusParent>

    </root>
    </xsl:template>


    <!-- IsNew Plus Parent Template(s) - Start-->

    <xsl:template match="P|E" mode="IsNewPlusParent">

    <!-- Print P or E (parent of new entities element-->
    <xsl:element name="{local-name()}">

    <!-- Add all attributes to the element-->
    <xsl:for-each select="@*">
    <xsl:copy-of select="."/>
    </xsl:for-each>

    <!-- Add all E nodes that are new-->
    <xsl:for-each select="child::E [@W='True']">
    <xsl:copy-of select="."/>
    </xsl:for-each>

    </xsl:element>


    </xsl:template>

    <!-- IsNew Plus Parent Template(s) - End-->


    </xsl:stylesheet>

    The problem with the above code is that it processes not only the
    existing parent but all of parents.

    Here is the output I would like:
    <root>
    <IsNewPlusParent>
    <P C="P" O="1">
    <E C="P_E1" O="1" W="True">
    <A C="P_E1A1" V="1" />
    <A C="P_E1A1" V="2" />
    </E>
    <E C="P_E10" O="13" W="True">
    <A C="P_E10A1" V="25" />
    <A C="P_E10A1" V="26" />
    <E C="P_E10E1" O="13_1" W="True">
    <A C="P_E10E1A1" V="25_1" />
    <A C="P_E10E1A1" V="26_1" />
    <E C="P_E10E1E1" O="13_1_1" W="True">
    <A C="P_E10E1E1A1" V="25_1_1" />
    <A C="P_E10E1E1A1" V="26_1_1" />
    </E>
    </E>
    </E>
    </P>
    <E C="P_E11" O="13">
    <E C="P_E11E1" O="13_1" W="True">
    <A C="P_E11E1A1" V="25_1" />
    <A C="P_E11E1A1" V="26_1" />
    <E C="P_E11E1E1" O="13_1_1" W="True">
    <A C="P_E11E1E1A1" V="25_1_1" />
    <A C="P_E11E1E1A1" V="26_1_1" />
    </E>
    </E>
    </E>
    <E C="P_E12" O="14">
    <E C="P_E12E1" O="15" W="True">
    <A C="P_E12E1A1" V="27_1" />
    </E>
    </E>
    </IsNewPlusParent>
    </root>

    Again, thank you reading this. Any help would be appreciated.
     
    Candle, Dec 8, 2006
    #1
    1. Advertising

  2. You said:
    "the nodes where the attribute
    W='True". These nodes need to be grouped together with the parent
    element tag, plus attributes, that does not have a W attribute."

    I'd suggest searching for the parent and processing downward from there.
    Your parents are
    //*[not @W][*/@W]
    .... that is, all nodes which do not have a W attribute but which have a
    child that does have this attribute.

    Having found the interesting parents, it appears you want to flatten
    their subtrees. (I don't understand why, but...) As you've already
    discovered, that can be done by simply recursing down their trees and
    copying the nodes you're interested in. However, I would suggest that
    you consider using xsl:copy rather than explicitly constructing a new
    element and copying the attributes to it; that'll make your life
    significantly easier, especially when you start dealing with namespaces.

    Hope that helps.

    --
    Joe Kesselman / Beware the fury of a patient man. -- John Dryden
     
    Joseph Kesselman, Dec 8, 2006
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    3,695
    A. Bolmarcich
    May 27, 2005
  2. jjouett
    Replies:
    7
    Views:
    1,159
    Harrie
    Oct 2, 2005
  3. KK
    Replies:
    2
    Views:
    735
    Big Brian
    Oct 14, 2003
  4. Candle

    XPath or XSL Transform Help

    Candle, Dec 11, 2006, in forum: XML
    Replies:
    2
    Views:
    424
    Candle
    Dec 12, 2006
  5. Joe Fawcett
    Replies:
    0
    Views:
    371
    Joe Fawcett
    Nov 21, 2007
Loading...

Share This Page