0

I've been trying to achieve the following output using XSLT but have really been struggling. Thank you in advance for any assistance.

From

<par>
   <run>Line one<break/>
        Line two<break/>
   </run>

   <run>Another para of text<break/>
   </run>

   <run>3rd para but no break</run>    
</par>

To

 <document>
   <para>Line one</para>
   <para>Line two</para>
   <para>Another para of text</para>
   <para>3rd para but no break</para>
 </document>

Thank you,

Dono

1
  • Please include some code to show what you tried Commented Dec 6, 2012 at 0:37

2 Answers 2

2

Here's a simple solution that is push-oriented and doesn't need <xsl:for-each>, <xsl:if>, or the self:: axis.

When this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="yes" />
  <xsl:strip-space elements="*" />

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

  <xsl:template match="run/text()">
     <para>
       <xsl:value-of select="normalize-space()" />
     </para>
  </xsl:template>

</xsl:stylesheet>

...is applied to the provided XML:

<par>
   <run>Line one<break/>
        Line two<break/>
   </run>

   <run>Another para of text<break/>
   </run>

   <run>3rd para but no break</run>    
</par>

...the wanted result is produced:

<document>
  <para>Line one</para>
  <para>Line two</para>
  <para>Another para of text</para>
  <para>3rd para but no break</para>
</document>
Sign up to request clarification or add additional context in comments.

Comments

0

Assuming that your <run> elements are only ever going to contain text and <break/> elements, and that you want to normalise whitespace and exclude <para> elements that would only contain whitespace (suggested by your desired output), the following should work:

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

    <xsl:output indent="yes"/>

    <xsl:template match="par">
        <document>
            <xsl:apply-templates select="*"/>
        </document>
    </xsl:template>

    <xsl:template match="run">
        <xsl:for-each select="text()">
            <xsl:if test="normalize-space(self::text()) != ''">
                <para>
                    <xsl:value-of select="normalize-space(self::text())"/>
                 </para>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Comments

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.