Re: [xsl] Help needed in recursively converting the flat xml to a heirarchical XML

Subject: Re: [xsl] Help needed in recursively converting the flat xml to a heirarchical XML
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Mon, 29 Mar 2004 14:48:05 -0500
Sridhar,

Hopefully other readers are tracking this too, in which case they may have some helpful observations. Again I can't give the problem the level of attention required for a complete solution, but maybe I can help you move forward.

Your code so far is encouraging: I think you're off to a good start.

To the points you ask about:

1. I am able to copy the <activity-state>, <concurrent-block>, <join> nodes to the respective locations. But the problem is there are still at the source location. I need to work on removing them too.

No problem. They are currently being copied because the only template they match is your first one:


<xsl:template match="/ | node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>

which, of course, says to copy them.

The way to avoid this is to match them with a template that does what you want (i.e. not to copy them).

To do this, the hard part is writing an XPath match pattern that will match only the nodes you want not to be copied. You know their names: activity-state, concurrent-block, and join. So you could start by simply having

<xsl:template match="activity-state | concurrent-block | join"/>

...which matches any of them, and does nothing with them (doesn't copy, doesn't do anything else either).

Of course, this will match all the activity-state, concurrent-block, and join nodes that are not matched with a higher priority by another template. So the XPath needs tweaking. If, for example, you wanted to suppress activity-state elements whose @name appears on a transition element someplace (and which therefore you don't need to copy), you could declare a key that would retrieve transition elements by their @to attribute

<xsl:key name="transitions" match="transition" use="@to"/>

and then have

<xsl:template match="activity-state[not(key('transitions',@name))]"/>

which would match only an activity-state that had no transition pointing to it. (Note: untested.)

2. Though I am able to copy the <concurrent-block> in case of nested, the problem here is only the <concuurent-block> does not contain any <activity-state>/<join>/<concuurent-block> nodes. You can see that when you transform the input xml with my xsl.

I don't follow this, sorry.


3.The number of join nodes copied are based on the no. of <activity-state> nodes refering to them, but my intention is to copy only one join node.. since according to the rules a fork can contain only join.

This can be done easily enough by restricting the selection of nodes to copy. So instead of <xsl:copy-of select="key('jname', $joinname)"/> you might have <xsl:copy-of select="key('jname', $joinname)[1]"/> (copies only the first of the nodes retrieved by the key).


4.Since the example given here is fairly a simple one, but inside the <concurrent-block> an <activity-state> can have a transition to another <activity-state>/<decision>/<concurrent-block> multiple times and the last <activity-state> will have a transition to a <join>. This code I have written will only go thru the entire list only once and populates the xml.

Yes. Have you considered instead of copy-of select="key(...)" trying to apply templates to the nodes selected by the key? Then they could have templates of their own, which would not only copy them, but would also contain the logic to retrieve and process the nodes to which they pointed.


These are the issues right now I am dealing with. May be you can guide me in achieving the desired results. I know I am missing some key point in my approach but I am not able to figure it out.
Is this approach correct in solving my problem?

It is, as far as you've gone. You just need to persist.


As an exercise, try changing

<xsl:copy-of select="key('jname', $joinname)"/>

to

<xsl:copy-of select="key('jname', $joinname)[1]"/>
  (this is short for key('jname', $joinname)[position() = 1] )

and see what difference that makes.

After trying that, instead of the copy-of try

<xsl:apply-templates select="key('jname', $joinname)[1]"/>

and add a template

<xsl:template match="join">
  <xsl:text>Join matched here!</xsl:text>
</xsl:template>

next to the other templates you have -- and observe what happens when you run the stylesheet. (Then see if you can fix it to do what you actually want it to do.)

Note: if you've also included a template that says <xsl:template match="join"/> for purposes of suppressing join elements, you'll run into trouble because the processor won't know which of the templates matching "join" to use. (It could signal an error, or use the latter one; in either case it's not using what you want it to.)

This particular issue is best dealt with by using modes: so you could have

<xsl:apply-templates select="key('jname', $joinname)[1]" mode="in-group"/>

in a template somewhere; then another template would match in the "in-group" mode for this case:

<xsl:template match="join" mode="in-group">
  <xsl:text>Join matched here, in a group!</xsl:text>
</xsl:template>

This should give you enough to chew on -- and put you in a better position to ask the more focused questions we can help you with more easily.

Areas for you to research might include XSL templates, how (and when) they match and how their priorities are assigned (what happens when more than one template matches a given node?), as well as XPath in general.

But you're making progress here! Excellent, considering how the node retrievals involved here make my head spin.

Good luck,
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================

Current Thread