Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old December 8th, 2006, 05:15 PM
Candle
Guest
 
Posts: n/a
Default XSL Transform Help Please

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:output 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.

  #2  
Old December 8th, 2006, 06:35 PM
Joseph Kesselman
Guest
 
Posts: n/a
Default Re: XSL Transform Help Please

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
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles