Это преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="body/text()" name="replaceNL">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText)">
<xsl:choose>
<xsl:when test="not(contains($pText, '
'))">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:value-of select=
"substring-before($pText,'
')"/>
</p>
<xsl:call-template name="replaceNL">
<xsl:with-param name="pText" select=
"substring-after($pText,'
')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
при применении к предоставленному документу XML:
<document>
<book>
<issue>1</issue>
<body>
“Dude, I can't believe you fed it to your cat. That's crazy!”
“Yeah, dude, he just cuddled up next to me and started purring.”
“Then what did he do?” “He just kept purring, man. He's been purring non-stop for like two weeks now. I can't even sleep.”
</body>
</book>
</document>
создает искомый, правильный результат :
<document>
<book>
<issue>1</issue>
<body>
<p/>
<p>“Dude, I can't believe you fed it to your cat. That's crazy!”</p>
<p> </p>
<p>“Yeah, dude, he just cuddled up next to me and started purring.”</p>
<p> </p>
<p>“Then what did he do?” “He just kept purring, man. He's been purring non-stop for like two weeks now. I can't even sleep.”</p>
</body>
</book>
</document>
Объяснение : Правило идентификации + рекурсивный именованный шаблон для переноса в p
каждой текстовой подстроки, окруженной символами NL.