XSLT Child node of a specific node

G

gregmcmullinjr

Hi All,

I would like to use XSLT to replace all <u> nodes that are children of
a <b> node with a new <heading> node. Also, if the <b> node has no
other children than remove it as well.
For example:


This would be some <b><u>Text</u></b>. It could <b> also maybe be like
<u>this</u>...</b>

to

This would be some <heading>Text</heading>. It could <b> also maybe be
like <heading>this</heading>...</b>

I've been trying something like:

<xsl:template match="//b">
...
</xsl:template>

with no success.

Could someone point me in the right direction?

Thanks!
 
A

A. Bolmarcich

Hi All,

I would like to use XSLT to replace all <u> nodes that are children of
a <b> node with a new <heading> node. Also, if the <b> node has no
other children than remove it as well.
For example:


This would be some <b><u>Text</u></b>. It could <b> also maybe be like
<u>this</u>...</b>

to

This would be some <heading>Text</heading>. It could <b> also maybe be
like <heading>this</heading>...</b>

I've been trying something like:

<xsl:template match="//b">
...
</xsl:template>

with no success.

Could someone point me in the right direction?


To replace a <u> that is a child of a <b> with <heading>, you can use

<xsl:template match="u[parent::b]">
<heading>
<xsl:apply-templates select="node()"/>
</heading>
</xsl:template>

To remove a <b> whose only child is a <u>, you can add

<xsl:template match="//b[u and count(node()) = 1]">
<xsl:apply-templates select="node()"/>
</xsl:template>

You will have to adjust the select attributes of the apply-templates
if you want the attributes of the replaced elements to be attributes
of the output <heading> elements.
These templates throw away the attributes of the replaced nodes.
 
G

gregmcmullinjr

A. Bolmarcich said:
Hi All,

I would like to use XSLT to replace all <u> nodes that are children of
a <b> node with a new <heading> node. Also, if the <b> node has no
other children than remove it as well.
For example:


This would be some <b><u>Text</u></b>. It could <b> also maybe be like
<u>this</u>...</b>

to

This would be some <heading>Text</heading>. It could <b> also maybe be
like <heading>this</heading>...</b>

I've been trying something like:

<xsl:template match="//b">
...
</xsl:template>

with no success.

Could someone point me in the right direction?


To replace a <u> that is a child of a <b> with <heading>, you can use

<xsl:template match="u[parent::b]">
<heading>
<xsl:apply-templates select="node()"/>
</heading>
</xsl:template>

To remove a <b> whose only child is a <u>, you can add

<xsl:template match="//b[u and count(node()) = 1]">
<xsl:apply-templates select="node()"/>
</xsl:template>

You will have to adjust the select attributes of the apply-templates
if you want the attributes of the replaced elements to be attributes
of the output <heading> elements.
These templates throw away the attributes of the replaced nodes.


Thanks for the reply Bolmarcich,

This works except that it places the new heading node in the wrong
place...
This is closer to what it actually looks like:

<notes>
<timestamp>
...
<content>
Here would be some <b><u>content...</u></b>
</content>
</timestamp>
<timestamp>
...
</timestamp>
</notes>

using your method results in:

<notes>
<timestamp>
...
<content>
<heading>content...</heading>
Here would be some <b><u>content...</u></b>
</content>
</timestamp>
<timestamp>
...
</timestamp>
</notes>

I would like the heading tag to actually replace the b and u tags...

I wish I knew more about XSLT to know the proper approach to this. Any
help is appreciated.
 
A

A. Bolmarcich

On 2006-10-20 said:
This works except that it places the new heading node in the wrong
place...
This is closer to what it actually looks like:

<notes>
<timestamp>
...
<content>
Here would be some <b><u>content...</u></b>
</content>
</timestamp>
<timestamp>
...
</timestamp>
</notes>

using your method results in:

<notes>
<timestamp>
...
<content>
<heading>content...</heading>
Here would be some <b><u>content...</u></b>
</content>
</timestamp>
<timestamp>
...
</timestamp>
</notes>

That is not the result that I get using xalan or saxon as the xlst
processor. Here are the files that I use.

input XML:

<?xml version="1.0"?>
<notes>
<timestamp>
...
<content>
Here would be some <b><u>content...</u></b>
</content>
</timestamp>
<timestamp>
...
</timestamp>
</notes>


XSLT (with a copy template in addition to the templates I suggested):

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

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

<xsl:template match="u[parent::b]">
<heading>
<xsl:apply-templates select="node()"/>
</heading>
</xsl:template>

<xsl:template match="//b[u and count(node()) = 1]">
<xsl:apply-templates select="node()"/>
</xsl:template>

</xsl:stylesheet>


output:
<?xml version="1.0" encoding="UTF-8"?><notes>
<timestamp>
...
<content>
Here would be some <heading>content...</heading>
</content>
</timestamp>
<timestamp>
...
</timestamp>


Please provide a complete example that demonstrates the problem.

In one template I may have followed what you gave in your original
posting too closly by using 'match="//b[u and count(node()) = 1]'.
It would be better to use 'match="b[u and count(node()) = 1]'.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top