Reputation: 244
I have xml like:
<item id="1">
<items>
<item id="2">Text2</item>
<item id="3">Text3</item>
</items>Text1
</item>
How to return text of <item id="1">
('Text1')?
<xsl:value-of select="item/text()"/>
returns nothing.
My XSLT is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="item"/>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="text()"/>
</xsl:template>
</xsl:stylesheet>
I dont know what else to type to commit my edits
Upvotes: 5
Views: 4266
Reputation: 243579
How to return text of
<item id="1">
('Text1')?<xsl:value-of select="item/text()"/>
returns nothing.
The item
element has more than one text-node children and the first of them happens to be a all-whitespace one -- this is why you get "nothing".
One way to test if the string value of a node isn't all-whitespace is by using the normalize-space()
function.
In a single Xpath expression, you want this:
/*/text()[normalize-space()][1]
Here is a complete transformation the result of which is the desired text node:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:copy-of select="text()[normalize-space()][1]"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<item id="1">
<items>
<item id="2">Text2</item>
<item id="3">Text3</item>
</items>Text1
</item>
the wanted, correct result is produced:
Text1
Upvotes: 5
Reputation: 101748
This should generally work:
<xsl:apply-templates select="item/text()" />
Incorporated into your XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="item_key" match="item" use="."/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<html>
<body>
<ul>
<xsl:apply-templates select="item"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="item">
<li>
<xsl:apply-templates select="text()"/>
</li>
</xsl:template>
</xsl:stylesheet>
When run on your sample input, the result is:
<html>
<body>
<ul>
<li>Text1
</li>
</ul>
</body>
</html>
Alternatively, this should work as well:
<xsl:copy-of select="item/text()" />
Upvotes: 2