Reputation: 811
I am writing an xml-to-json converter using xslt. I convert
<raw>
<id>0</id>
<type>label</type>
<title>Test</title>
<uri>...</uri>
</raw>
to
{ "id" = "0", "type"="label", "title" = "Test", "uri" = "..." }
using an <xsl:for-each>
iterating over the child nodes of tag <raw>
, and adding commas with <xsl:if test="following-sibling::*">, </xsl:if>
.
However, if I want to change the above xml to use attributes instead of child nodes:
<raw id="0" type="label" title="Test" uri="..." />
the following-sibling::*
test fails and no commas are added. Is there an equivalent of following-sibling::*
that works for attributes? If not, is it possible to do what I intend here?
Upvotes: 2
Views: 856
Reputation: 3738
The following-sibling
axis can be an expensive operation (depending on how many attributes we're talking about). Here's a fairly streamlined solution that accomplishes what you're asking for (and does so without following-sibling
or any other complicated axis).
When this XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="no" method="text" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:text>{ </xsl:text>
<xsl:apply-templates select="raw/@*" />
<xsl:text> }</xsl:text>
</xsl:template>
<xsl:template match="@*">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of
select="concat('"', name(), '" = "', ., '"')" />
</xsl:template>
</xsl:stylesheet>
...is run against your provided XML:
<raw id="0" type="label" title="Test" uri="..."/>
...the desired result is produced:
{ "id" = "0", "type"="label", "title" = "Test", "uri" = "..." }
Upvotes: 2
Reputation: 56162
Use this XPath for both cases:
<xsl:if test="position() != last()">
Upvotes: 4