tags:

views:

55

answers:

3

I have a major problem finding a way to add a space between two child elements.

<aaa>
    I want to add <bbb>a</bbb><ccc>space</ccc> between two words.
</aaa>

I want to add a space between the "a" and "space" words if the ccc element follows the bbb element immediately. Currently I apply template at aaa element level, and then handle bbb and ccc element in separate templates.

I have no idea how to detect this </bbb><ccc> pattern in advance.

Note: I do not know what words will be inside the bbb and ccc elements.

+2  A: 

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes"/>

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

 <xsl:template match=
   "b[. = 'a'
   and
    following-sibling::node()
                    [1]
                    [self::i
                   and
                     . = 'boy'
                    ]
      ]
   ">
   <xsl:call-template name="identity"/>
   <xsl:text> </xsl:text>
 </xsl:template>
</xsl:stylesheet>

when performed on the provided XML document:

<aaa>
    I am <b>a</b><i>boy</i>.
</aaa>

produces the wanted, correct result:

<aaa>
    I am <b>a</b> <i>boy</i>.
</aaa>

Do note:

  1. The use of the identity rule to copy all nodes.

  2. The overriding of the identity rule with a specific template to carry out the addition of the space character exactly between the specified <b> and <i> nodes.

  3. The match (XPath expression) pattern used to match exactly the wanted <b> node after which the space is to be inserted.

  4. The code reuse of the template rule, both being applied and called by name.

Dimitre Novatchev
+1, nice. For a more general version for adding a space between any adjacent elements inside an `aaa` element, the match expression of the latter template could be written as `aaa/*[following-sibling::node()[1]/self::*]`
Jukka Matilainen
A: 

Thanks.

Does it work in all general case for </b><i> pattern? I mean, if I don't know the words inside the <b></b> and <i></i>.

Sorry for asking many questions, I am a beginner in XSLT.

Wilson
Please, ask this as a separate (new) question. Never provide new questions as answers to your own question. Use comments instead.
Dimitre Novatchev
A: 

Problem solved. Thank you very much for your information.

Wilson
If "problem solved", you are supposed to accept the answer. Please, do so (click on the check mark). :)Never provide new questions as answers to your own question. Use comments instead.
Dimitre Novatchev
OK. Sorry, I am new to this site. Thanks.
Wilson