Reputation: 6119
There is a xml (for the example the xml is simplified)
<object attr1="1" attr2="2">
xxxxxxxxx
<someattrs>
<someattr1>a</someattr1>
<someattr2>b</someattr2>
<someattr3>c</someattr3>
<someattr4 attr3="3">
yyyyyyy
<someattr5>d</someattr5>
<someattr6>e</someattr6>
<someattr7 attr8="f">
<![CDATA[ zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz ]]>
</someattr7>
</someattr4>
</someattrs>
</object>
With the xls transformation which is meant to transform any xml that has attributes into element-centric xml:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
</xsl:template>
</xsl:stylesheet>
the xml transforms to
<?xml version="1.0" encoding="UTF-8"?>
<object>
<attr1>1</attr1>
<attr2>2</attr2>
xxxxxxxxx
<someattrs>
<someattr1>a</someattr1>
<someattr2>b</someattr2>
<someattr3>c</someattr3>
<someattr4>
<attr3>3</attr3>
yyyyyyy
<someattr5>d</someattr5>
<someattr6>e</someattr6>
<someattr7>
<attr8>f</attr8>
zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz
</someattr7>
</someattr4>
</someattrs>
</object>
The problem is that any free text() that appears in the source xml didn't go in it's own tag (let's put all free texts to elements with names "sometext") in the final xml. The text "xxxxxxxxx" should go in its own tag <sometext>xxxxxxxxx</sometext>
and "yyyyyyy" should go in its own tag <sometext>yyyyyyy</sometext>
.
What is the transformation to get the following xml?
<?xml version="1.0" encoding="UTF-8"?>
<object>
<attr1>1</attr1>
<attr2>2</attr2>
<sometext>xxxxxxxxx</sometext>
<someattrs>
<someattr1>a</someattr1>
<someattr2>b</someattr2>
<someattr3>c</someattr3>
<someattr4>
<attr3>3</attr3>
<sometext>yyyyyyy</sometext>
<someattr5>d</someattr5>
<someattr6>e</someattr6>
<someattr7>
<attr8>f</attr8>
<sometext>zzzzzzz zzzzzz zzzzzz zzzzzzzzzzzz</sometext>
</someattr7>
</someattr4>
</someattrs>
</object>
Upvotes: 0
Views: 334
Reputation: 8982
Get rid of formatting-only text nodes:
<xsl:strip-space elements="*"/>
Create <sometext>
elements from text-only nodes.
<xsl:template match="object/text()">
<sometext><xsl:value-of select="normalize-space(.)"/></sometext>
</xsl:template>
UPDATE
General solution for any element:
<xsl:template match="*[*|@*]/text()">
<sometext><xsl:value-of select="normalize-space(.)"/></sometext>
</xsl:template>
Upvotes: 1
Reputation: 7173
you could try:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
</xsl:template>
<xsl:template match="*[@*]/text()">
<sometext><xsl:value-of select="normalize-space(.)"/></sometext>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1