simplifying transform

D

David Schwartz

So, I've got some elements that refer to other elements based on one
id. Each of the referent elements actually have a second id (don't
ask) which I'd like to use instead (so I can drop the extra id). So,
based on the following data, I'd like to keep everything the same
except for having all tagC's referring to tagB's based on id1 instead
of id2. Again, everything else would be the same. I can figure out how
to make the switch in tagC's just fine but do I have to write a
template for every type of tag as well? Sure hope not!

<root>
<tagA>foo</tagA>
<tagB id1="XXX" id2=YYY">boo</tagB>
<tagC ref="YYY">pie</tagC>
<tagD>bar</tagD>
</root>

TIA,
David
 
M

Martin Honnen

David said:
So, I've got some elements that refer to other elements based on one
id. Each of the referent elements actually have a second id (don't
ask) which I'd like to use instead (so I can drop the extra id). So,
based on the following data, I'd like to keep everything the same
except for having all tagC's referring to tagB's based on id1 instead
of id2. Again, everything else would be the same. I can figure out how
to make the switch in tagC's just fine but do I have to write a
template for every type of tag as well? Sure hope not!

<root>
<tagA>foo</tagA>
<tagB id1="XXX" id2=YYY">boo</tagB>
<tagC ref="YYY">pie</tagC>
<tagD>bar</tagD>
</root>

Using
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

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

<xsl:template match="@id2"/>

<xsl:template match="tagC">
<xsl:copy>
<xsl:attribute name="ref">
<xsl:value-of select="../*[@id2 = current()/@ref]/@id1"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

should do, if I understand correctly what you want to achieve.
 
D

David Schwartz

Thanks for your help Martin. I'd like to explore this in steps if
possible. So when I execute the following transform, I don't get any
attributes. Any ideas as to why? Shouldn't I get all the nodes in
their original state?

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"
extension-element-prefixes="redirect">

<xsl:template match="@* | node()">
<redirect:write file="transformed.xml">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</redirect:write>
</xsl:template>

TIA!
David
 
D

David Carlisle

David said:
Thanks for your help Martin. I'd like to explore this in steps if
possible. So when I execute the following transform, I don't get any
attributes. Any ideas as to why? Shouldn't I get all the nodes in
their original state?

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"
extension-element-prefixes="redirect">

<xsl:template match="@* | node()">
<redirect:write file="transformed.xml">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</redirect:write>
</xsl:template>

TIA!
David

That template is generating a file (with the same noame over and over
again) for every element, in the case of attributes it tries to copy the
attribute on its own to a new file but without an element to hold it,
that can't work.

If you just want to redirect the result of an identity transform then
you don't want a new file on every element, just the root:

<xsl:template match="@* | node()">

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

</xsl:template>

<xsl:template match="/">
<redirect:write file="transformed.xml">

<xsl:apply-templates/>

</redirect:write>
</xsl:template>

David
 
D

David Schwartz

Actually, both stylesheets produce a file with the same number of
elements. The stylesheet you provided David does include the
attributes though so thanks!

So, now that I'm successfully creating all the tags, how do I change
the values of the ref attribute in just the tagC elements?

Thanks again!

David
 
M

Martin Honnen

David said:
Actually, both stylesheets produce a file with the same number of
elements. The stylesheet you provided David does include the
attributes though so thanks!

So, now that I'm successfully creating all the tags, how do I change
the values of the ref attribute in just the tagC elements?

As suggested earlier:

<xsl:template match="@* | node()">

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

</xsl:template>

<xsl:template match="/">
<redirect:write file="transformed.xml">

<xsl:apply-templates/>

</redirect:write>
</xsl:template>

<xsl:template match="@id2"/>

<xsl:template match="tagC">
<xsl:copy>
<xsl:attribute name="ref">
<xsl:value-of select="../*[@id2 = current()/@ref]/@id1"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
 
D

David Schwartz

Thanks for everyone's help! While I wish I understood the stylesheet
better but it's getting the job done.

Thanks again,
David
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top