copying all but one type of Nodes in XSLT

W

Wizfrog

Hello,

I'm unsing well-formed XML HTML tags as my formatted "Description"
content in a XML Database, so I have stuff of the sort:

<Description lang='en'><b>This is bold Text</b> and this is not<i>and
this is italic text</i></Description>

So far, nothing too dramatic, when I want to reproduce this as an HTML
output, I used the <xsl:copy-of> command to copy the whole node over
to my HTML output.

Now here comes where I have an issue:

I want to use a specific tag <spec name='specname'/> to insert
"Specifications" related to the product WITHIN the formatted text...
so it could be anywhere under <Description> or a <b> tag, or a <i>
tag ...

The idea is that products are built out of other products, and I want
to be able to have the specification propagate through to the higher
level products, so I only want to "reference" the spec name in the
Description, and pull it out from the lower level product at the time
of output.

So, my problem is to "fill in" my <spec name='specname'/> tag with its
content coming from somewhere else.
The <xsl:copy-of> can no longer be used here, and it doesn't do the
job, but then is there an easy way to "transfer" all of the XML/HTML
and just replace the tag i want to replace?

I obviously need to parse the whole thing, but tags can be anything,
anywhere, (from the selection of formatting tags <b>, <i>, <u>, <br/>,
<p>, <sub>, <sup> etc...)

I'm not so proficient in XPath to figure out what would be the path I
want to select to transfer all tags but my <spec> tag, and when
bumping into one, replacing it with my data.

any insight?

Suggestion appreciated!

Thanks
 
M

Martin Honnen

Wizfrog said:
So, my problem is to "fill in" my <spec name='specname'/> tag with its
content coming from somewhere else.
The <xsl:copy-of> can no longer be used here, and it doesn't do the
job, but then is there an easy way to "transfer" all of the XML/HTML
and just replace the tag i want to replace?

I obviously need to parse the whole thing, but tags can be anything,
anywhere, (from the selection of formatting tags <b>, <i>, <u>, <br/>,
<p>, <sub>, <sup> etc...)

It is rather easy, start with the identity transformation template
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
then add other templates as needed, for instance
<xsl:template match="spec[@name = 'specname']">
<!-- do what is needed here for those spec elements -->
</xsl:template>
 
W

Wizfrog

Wizfrog said:
So, my problem is to "fill in" my <spec name='specname'/> tag with its
content coming from somewhere else.
The <xsl:copy-of> can no longer be used here, and it doesn't do the
job, but then is there an easy way to "transfer" all of the XML/HTML
and just replace the tag i want to replace?
I obviously need to parse the whole thing, but tags can be anything,
anywhere, (from the selection of formatting tags <b>, <i>, <u>, <br/>,
<p>, <sub>, <sup> etc...)

It is rather easy, start with the identity transformation template
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
then add other templates as needed, for instance
<xsl:template match="spec[@name = 'specname']">
<!-- do what is needed here for those spec elements -->
</xsl:template>

Hi,

I tried this, but it always seem to use the @* | node() by default,
and never gets to the match='spec[...]' template even when getting to
a <spec> tag...

any way to filter out the specific tag?
 
W

Wizfrog

I tried this:

<xsl:template match="@* | node()">
<xsl:choose>
<xsl:when test="@name">
print Spec here
</xsl:when>
<xsl:eek:therwise>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

and it works fine, but I am not sure why the following doesn't:

<xsl:template match="@* | node()">
<xsl:choose>
<xsl:when test="spec">
print Spec here
</xsl:when>
<xsl:eek:therwise>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>

ideally I need to process more than 1 attribute from the <spec> tag,
so i'd like to trigger it on that node name, not on the attribute

any idea?
 
J

Joe Kesselman

Wizfrog said:
I tried this, but it always seem to use the @* | node() by default,
and never gets to the match='spec[...]' template even when getting to
a <spec> tag...

In that case, the spec element isn't matching. Either the predicate is
wrong or you've got namespaces involved. Think about why, or give us
enough information to diagnose.
 
J

Joe Kesselman

Wizfrog said:
<xsl:when test="@name">

True when the current node has a name attribute said:
<xsl:when test="spec">

True when the current node has a spec element child, ie the <spec>'s
parent.

xsl:when is not the best way to do this -- use templates -- but if you
must, you could try
<xsl:when test="self::spec">
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top