Reputation: 14552
I'm trying to transform this XML document:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<data>
<entry>
<databit>30.11.2012</databit>
<databit>Foo</databit>
<databit>Key: Value<br />Key: Value<br /> ... Key: Value</databit>
<databit>some Foo content</databit>
<databit>more Foo content</databit>
</entry>
<entry>
...
</entry>
...
</data>
The number of the key-value pairs is variable. The separator is always a <br />
tag.
The output should look like this:
<data>
<entry>
<date>30.11.2012</date>
<title>Foo</title>
<info>
<part key="Key" value="Value" />
<part key="Key" value="Value" />
<part key="Key" value="Value" />
</info>
<databit>some Foo content</databit>
<databit>more Foo content</databit>
</entry>
<entry>
...
</entry>
...
</data>
Here is the XSLT document I've written:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<data>
<xsl:for-each select="/data/entry">
<entry>
<date>
<xsl:value-of select="databit[1]"/>
</date>
<title>
<xsl:value-of select="databit[2]"/>
</title>
<info>
<xsl:value-of select="databit[3]"/>
</info>
<category>
<xsl:value-of select="databit[4]"/>
</category>
<status>
<xsl:value-of select="databit[5]"/>
</status>
</entry>
</xsl:for-each>
</data>
</xsl:template>
</xsl:stylesheet>
But I have no idea, how to transform the info
.
Upvotes: 0
Views: 129
Reputation: 13986
This stylesheet should create the desired transformation. The stylesheet assumes that key and value are always separated with :
and it strips the colon and space character, but no other characters. Use normalize-space()
if whitespace removal is needed.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="databit[1]">
<date>
<xsl:apply-templates/>
</date>
</xsl:template>
<xsl:template match="databit[2]">
<title>
<xsl:apply-templates/>
</title>
</xsl:template>
<xsl:template match="databit[3]">
<info>
<xsl:apply-templates/>
</info>
</xsl:template>
<xsl:template match="databit[3]/text()">
<part key="{substring-before(., ':')}" value="{substring(substring-after(., ':'), 2)}"/>
</xsl:template>
<xsl:template match="databit[3]/br"/>
</xsl:stylesheet>
Some points on the stylesheet
<databit>
element are expected to be key-value pairs.<part>
elements are added using an XPath expression inside braces (an attribute value template). Other method to add them is to use <xsl:attribute>
element.<br>
is suppressed from copying by using an empty template.Upvotes: 2