-1

In the below example we are trying to handle 'BR' element under the 'P' element and convert into the seprate paragraph using 'XSLT 1.0':

Can anyone help.

INPUT XML:

<?xml version="1.0" encoding="UTF-8"?>
<CONTENT>
<P>A. 05° 55’ 47.81” S – 106° 32’ 10.76” E<BR/>B. 05° 55’ 47.81” S – 106° 34’ 10.76” E<BR/>C. 05° 55’ 47.81” S – 106° 36’ 10.76” E<BR/>D. 05° 57’ 47.81” S – 106° 32’ 10.76” E<BR/>E. 05° 57’ 47.81’’S – 106° 34’ 10.76’’E<BR/>F. 05° 57’ 47.81’’S – 106° 36’ 10.76’’E<BR/>G. 05° 59’ 47.81’’S – 106° 32’ 10.76’’E<BR/>H. 05° 59’ 47.81’’S – 106° 34’ 10.76’’E<BR/>I. 05° 59’ 47.81’’S – 106° 36’ 10.76’’E</P>
</CONTENT>

EXPECTED OUTPUT:

<?xml version="1.0" encoding="UTF-8"?>
<CONTENT>
<P>A. 05° 55’ 47.81” S – 106° 32’ 10.76” E</P>
<P>B. 05° 55’ 47.81” S – 106° 34’ 10.76” E</P>
<P>C. 05° 55’ 47.81” S – 106° 36’ 10.76” E</P>
<P>D. 05° 57’ 47.81” S – 106° 32’ 10.76” E</P>
<P>E. 05° 57’ 47.81’’S – 106° 34’ 10.76’’E</P>
<P>F. 05° 57’ 47.81’’S – 106° 36’ 10.76’’E</P>
<P>G. 05° 59’ 47.81’’S – 106° 32’ 10.76’’E</P>
<P>H. 05° 59’ 47.81’’S – 106° 34’ 10.76’’E</P>
<P>I. 05° 59’ 47.81’’S – 106° 36’ 10.76’’E</P>
</CONTENT>

XSLT CODE:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

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

</xsl:stylesheet>

Reference Link: https://xsltfiddle.liberty-development.net/bEJbVso/1

Umaima
  • 137
  • 1
  • 1
  • 9

2 Answers2

2

we are trying to handle 'BR' element under the 'P' element and convert into the seprate paragraph

Actually, you do not need to handle the BR elements at all.

All you need to do is address the individual text nodes (already separated by the BR element) and convert each one of these into a separate P element:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/CONTENT">
    <xsl:copy>
        <xsl:for-each select="P/text()">
            <P>
                <xsl:value-of select="."/>
            </P>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
-2

Try this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  >
  
  <xsl:template match="P[BR]">
    <p><xsl:value-of select="BR[1]/preceding-sibling::text()"/></p>
    <xsl:apply-templates select="BR"/>
  </xsl:template>
  
  <xsl:template match="P/BR[following-sibling::BR]">
    <p><xsl:value-of select="following-sibling::BR[1]/preceding-sibling::node()[1][self::text()]"/></p>
  </xsl:template>

  <xsl:template match="P/BR[not(following-sibling::BR)]">
    <p><xsl:value-of select="following-sibling::text()"/></p>
  </xsl:template>

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

</xsl:stylesheet>
Siebe Jongebloed
  • 3,906
  • 2
  • 14
  • 19
  • Compared with [michael.hor257k's answer](https://stackoverflow.com/a/67054121/4453460), this one has three templates that are _almost, but not exactly, identical_: in a longish stylesheet that sometimes needs to be updated they could be difficult to maintain (typical situation: you remember to fix one or two, and forget the others). – lfurini Apr 12 '21 at 13:42
  • 1
    His answer is the easiest to understand and maybe the easiest to maintain...depending if other inline-elements are introduces. My xslt will also create empty p if there are two br with no text in between and if after the last br there is no text-node. – Siebe Jongebloed Apr 12 '21 at 13:57