supress matching

P

patrik.nyman

Suppose I have the following xml-text:

Some text before.<A/>
<B>Text in the B-element.</B>
Some text after.

And I want:

Some text before.
<C>Text in the B-element.</C>
Some text after

I have tried something like:

<xsl:template match="A">
<C><xsl:apply-templates select="B"/></C>
</xsl:template>

<xsl:template match="B">
<xsl:apply-templates/>
</xsl:template>

But that results in:

Some text before.
<C>Text in the B-element.</C>
Text in the B-element.
Some text after

So basically, how can I call template B from
within template A, and then not having B match
again?
 
M

Martin Honnen

Suppose I have the following xml-text:

Some text before.<A/>
<B>Text in the B-element.</B>
Some text after.

That stuff is not well-formed. At least show us the element that markup
is contained in.
And I want:

Some text before.
<C>Text in the B-element.</C>
Some text after

So you want to remove the empty A element, you want to replace the B
element with a C element but preserves its content. And you want to
copy text nodes outside of B. So doing e.g.

<xsl:template match="A"/>

ignores the A elements,

<xsl:template match="B">
<C>
<xsl:apply-templates/>
</C>
</xsl:template>

transforms B into C elements and the built-in template

<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>

copies text nodes.
 
M

Magnus Henriksson

Suppose I have the following xml-text:

Some text before.<A/>
<B>Text in the B-element.</B>
Some text after.

And I want:

Some text before.
<C>Text in the B-element.</C>
Some text after

I have tried something like:

<xsl:template match="A">
<C><xsl:apply-templates select="B"/></C>
</xsl:template>

<xsl:template match="B">
<xsl:apply-templates/>
</xsl:template>

But that results in:

Some text before.
<C>Text in the B-element.</C>
Text in the B-element.
Some text after

So basically, how can I call template B from
within template A, and then not having B match
again?

<xsl:template match="A"/>

<xsl:template match="B">
<C>
<xsl:apply-templates/>
</C>
</xsl:template>


// Magnus
 
P

patrik.nyman

OK, sorry, I tried to make it short, but it became
confusing instead. Here's the whole story.

I'm working with a text that contains the following
structures:

<p>
Some lines of text.
Some lines of text. *)
</p>

<footnote>
Text in the footnote. It continues ...
</footnote>

<pagebreak/>

<p>
Some more lines of text.
</p>

<footnote>
... in the next footnote element!
</footnote>

I need to preserve this structure, but I also need to
be able to output

Some lines of text.
Some lines of text. *)\footnote{%
Text in the footnote. It continues ...
... in the next footnote element!
}

Some more lines of text.

To this end, I apply the following markup:

<p>
Some lines of text.
Some lines of text. *)<fn n="1"/>
</p>

<footnote n="1">
Text in the footnote. It continues ...
</footnote>

<pagebreak/>

<p>
Some more lines of text.
</p>

<footnote n="1">
... in the next footnote element!
</footnote>

I have tried the following templates:

<xsl:template match="fn">
<xsl:param name="notenr" select="@n"/>\footnote{%
<xsl:apply-templates select="following::fotnottext[@n eq
$notenr]"/>}
</xsl:template>

<xsl:template match="footnote">
<xsl:apply-templates/>
</xsl:template>

But I get:

Some lines of text.
Some lines of text. *)\footnote{%
Text in the footnote. It continues ...
... in the next footnote element!
}

Text in the footnote. It continues ... <-----

Some more lines of text.

... in the next footnote element! <-----

The lines marked with <----- must be removed somehow.
I hope this makes it clearer what I want.
 
D

Dimitre Novatchev

Read about the "mode" attribute of the <xsl:template> instruction and of the
<xsl:apply-templates> instruction.

Then use this attribute in your XSLT code.


Cheers,
Dimitre Novatchev
 
R

Richard Tobin

Some text before.<A/>
<B>Text in the B-element.</B>
Some text after.

And I want:

Some text before.
<C>Text in the B-element.</C>
Some text after

I have tried something like:

<xsl:template match="A">
<C><xsl:apply-templates select="B"/></C>
</xsl:template>

<xsl:template match="B">
<xsl:apply-templates/>
</xsl:template>

You can't be doing that! The B is not inside the A so select="B"
won't select anything. Presumably you are using following-sibling or
something similar.

You could change the template of the element containing A and B to
not call apply-templates on B - perhaps:

<xsl:apply-templates select="*[not(self::B)]"/>

or you could use modes. Have a plain template for B that does nothing,
and a template in mode really-do-it:

<xsl:template match="B" mode="really-do-it">
<xsl:apply-templates/>
</xsl:template>

Then have the template for A call apply-templates on B with
mode="really-do-it".

-- Richard
 
P

patrik.nyman

Richard said:
You can't be doing that! The B is not inside the A so select="B"
won't select anything. Presumably you are using following-sibling or
something similar.

You're right, of course. I over-simplified my example.
or you could use modes. Have a plain template for B that does nothing,
and a template in mode really-do-it:

Yes, that does it. Wonderful! Thanks a lot to all who answered.

/Patrik
 

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

No members online now.

Forum statistics

Threads
474,007
Messages
2,570,266
Members
46,865
Latest member
AveryHamme

Latest Threads

Top