0

I have an XML similar to this one:

<parent>
    <child>child's text</child>
    <child>other child's text</child>
    parent's text
</parent>

Note that it's allowed to have multiple child elements.

I'd like to know if the parent element has text outside of its children.

I've come up with this solution:

<xsl:if test="normalize-space(parent/child[1]) = normalize-space(parent)">
    <xsl:text>No parent text</xsl:text>
</xsl:if>

I use parent/child[1] because the normalize-space function doesn't accept a sequence as it's argument.

Is there a better way to do this?

(I've found this question on the topic but the answer is incorrect or the question is different)

Community
  • 1
  • 1
gombost
  • 317
  • 1
  • 3
  • 9

2 Answers2

1

Use text() to explicitly refer to text nodes.

The better way to do this is:

<xsl:if test="parent/text()[not(parent::child)]">
  <!--This parent element has text nodes-->
</xsl:if>

Or else, you could write a separate template:

<xsl:template match="text()[parent::parent]">
   <xsl:text>parent element with text nodes!</xsl:text>
</xsl:template>
Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
  • parent/text() returns the concatenation of the parent's text plus all of its children's. – gombost Feb 05 '14 at 10:47
  • Sorry, not the concatenation. It returns multiple text nodes containing the node's text and its children's. Therefore it doesn't work with normalize-space in my solution. – gombost Feb 05 '14 at 10:55
1

This template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
<xsl:strip-space elements="*"/>    
    <xsl:template match="/">
        <xsl:choose>
            <xsl:when test="parent/child::text()">
                true
            </xsl:when>
            <xsl:otherwise>false</xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

when applied to your input XML, returns

true

when applied at the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <child>child's text</child>
    <child>other child's text</child>
</parent>

returns

false
Joel M. Lamsen
  • 7,143
  • 1
  • 12
  • 14