1

I can't find a working solution to my problem. I need to merge two elements with the same name into one when they are in specific position in the document: tags hi when between them stays lb break='no'. How can I do that? The xml code is:

<p>
 <lb n="28"/> Lorem ipsum dolor sit
 <lb n="29"/> amet, consectetur, <hi rend="u">adi</hi>
 <lb n="30" break="no"/><hi rend="u">pisci</hi> elit...
</p>

I transform it into a floating text without line breakes and as there is a hyphen there I need to merge the two elements into one. Now I get always a blank between them.

<p>Lorem ipsum dolor sit amet, consectetur <span class="u">adipisici</span> elit...</p>

Thanks a lot!

1
  • Can you use XSLT 2.0 with an XSLT 2.0 processor like Saxon 9? Commented Jul 15, 2013 at 11:38

1 Answer 1

1

Assuming an XSLT 2.0 processor like Saxon 9 or XmlPrime you can use

<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:template match="p">
  <xsl:copy>
    <xsl:for-each-group select="node() except text()[not(normalize-space())]"
      group-adjacent="self::hi or self::lb[@break = 'no']">
      <xsl:choose>
        <xsl:when test="current-grouping-key()">
          <span class="{current-group()[self::hi][1]/@rend}">
            <xsl:apply-templates select="current-group()/node()"/>
          </span>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="current-group()"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

to transform

<p>
 <lb n="28"/> Lorem ipsum dolor sit
 <lb n="29"/> amet, consectetur, <hi rend="u">adi</hi>
 <lb n="30" break="no"/><hi rend="u">pisci</hi> elit...
</p>

into

<p> Lorem ipsum dolor sit
  amet, consectetur, <span class="u">adipisci</span> elit...
</p>
Sign up to request clarification or add additional context in comments.

3 Comments

Hi! Thanks for your suggestion! But somehow on my code the result is so, that now I get no whitespace between hi tags when lb tag stays between them. It's already better, but a new problem arises. I have several namespases in XSL and despite exclude-result-prefixes="#all" in all p tags I have one of the namespaces. What should I do?))
Edit your question with a more complex sample of the XML you have and the corresponding transformation result you want. As for the namespaces, let's first try to fix the transformation you asked for, then we can look at such problems. If the input has a p in a certain namespace and the output needs a HTML p in no namespace then change the <xsl:copy><xsl:for-each-group ...>...</xsl:for-each-group></xsl:copy> to <p><xsl:for-each-group ...>...</xsl:for-each-group></p>.
Thanks! I have substituted <xsl:copy> for <p> and the namespaces have dissappeared! I'll try to rewrite my xsl in order to understand what goes wrong and if I can't get it I'll post the extended sample of xml and xsl. Thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.