1

I am using XSLT to transform XML.

I am currently hard-coding each attribute name like so:

    <xsl:for-each select="variable">
    {
         "name" : "<xsl:value-of select="@name" />",
         "value" : "<xsl:value-of select="@value" />"
    }
    </xsl:for-each>

But this seems really messy. Is there a way to dynamically create the key value pairs from the attributes without having to hardcode each attribute name individually ? i.e. Above I have specified :

"name" : "<xsl:value-of select="@name" />"

Is there a way to change it so that I just use some variable in loop so it is like:

(pseudocode:)

        <for each attribute in my element>
        {
             "attribute.name" : "attribute.value",
        }
        </xsl:for-each>

EDIT: Edited the question, so JSON is irrelevant to what I'm trying to do. Just trying to transform the name value pairs as described above, without hard coding.

5
  • XSLT is incapable of outputting JSON. JSON has pretty complex rules none of which XSLT knows anything about. Any XSLT code you write in this fashion will at some point produce invalid JSON and you'd be wise never to put it into production. Use an appropriate tool, something that contains a JSON serializer. Commented Oct 25, 2014 at 10:20
  • XSLT transforms an XML document into anything you want to transform it to. I'm sure there are complex rules to JSON, but what I'm trying to do is as simple as the code above. For the purposes of solving my problem, JSON doesn't really matter, since what I'm trying to do is just write XSLT so I can extract the attribute name dynamically and use it, instead of hardcoding Commented Oct 25, 2014 at 10:26
  • That's where you are mistaken. XSLT can transform XML into three things. XML, HTML and Plain Text. JSON is not a valid output target. (JSON is not plain text in the same manner that HTML is not plain text.) JSON is a serialized data structure, just like XML, and you cannot use XSLT to produce it, period. You can use XSLT to produce something that kind of looks like JSON and hopefully can be parsed at the receiving end. But you cannot be sure. And that's why you really should use an appropriate tool for your job. There are plenty. Don't use a shoe on a nail when there is a hammer around. Commented Oct 25, 2014 at 10:30
  • Currently the code I have works for me, and meets my requirements. I appreciate your concern and will be careful how I use my code. But for now, all I'm trying to do is just removing my hardcoding from my XSLT transform. JSON is no longer relevant to this question. Commented Oct 25, 2014 at 10:34
  • Sure you can <xsl:for-each select="@*"> and use <xsl:value-of select="name()" /> and <xsl:value-of select="." />. It's your funeral, you have been warned. Commented Oct 25, 2014 at 10:42

1 Answer 1

1

Assuming the context of your code snippet is a template matching the element with the said attributes. The gist of it was already mentioned by @Tomalak:

<xsl:for-each select="@*">
  <xsl:text>{&#10;"</xsl:text>
  <xsl:value-of select="name()"/>
  <xsl:text>" : "</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>",&#10;}</xsl:text>
</xsl:for-each>

(Not tested since you did not show a complete stylesheet.)

Always control whitespace serialization by putting textual content inside xsl:text elements. As mentioned already, this is fine if you're interested in the general idea of retrieving attribute name and value pairs - but not necessarily if you'd like to output actual JSON.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.