问题
I have an incoming XML file with a list structure:
<list>
<listItem>
<name>elementOne</name>
<value>elementOneValue</name>
</listItem>
<listItem>
<name>elementTwo</name>
<value>elementTwoValue</name>
</listItem>
</list>
Which I am trying to convert to this structure:
<elementOne>elementOneValue</elementOne>
<elementTwo>elementTwoValue</elementTwo>
This is easy logic to implement with XSL, but I'm running into complications.
<xsl:for-each select="/list/listItem">
<xsl:element name="<xsl:value-of select="name"/>">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:for-each>
Doesn't work because I assume the sequential double quotes are breaking the <xsl:element>
tag
<xsl:for-each select="/list/listItem">
<<xsl:value-of select="name"/>>
<xsl:value-of select="value"/>
</<xsl:value-of select="name"/>>
</xsl:for-each>
Doesn't work because I can't use <<
or >>
and
<xsl:for-each select="/list/listItem">
<<xsl:value-of select="name"/>>
<xsl:value-of select="value"/>
</<xsl:value-of select="name"/>>
</xsl:for-each>
Doesn't work because I end up with > and < in my code instead of XML parseable <
or >
. I expected this to be a very easy solution but I can't find any records for it on the internet. What is the simple fix I'm overlooking?
回答1:
Here is a complete and short solution, using the <xsl:element> XSLT instruction:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="listItem">
<xsl:element name="{name}">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document (corrected to be well-formed):
<list>
<listItem>
<name>elementOne</name>
<value>elementOneValue</value>
</listItem>
<listItem>
<name>elementTwo</name>
<value>elementTwoValue</value>
</listItem>
</list>
the wanted result is produced:
<elementOne>elementOneValue</elementOne>
<elementTwo>elementTwoValue</elementTwo>
Do note:
The use of the
<xsl:element>
instruction to create an element with statically unknown name.The use of AVT (Attribute-Value-Template) to specify the
name
attribute in a compact and more readable way.It is possible for an error to be raised if the string values of
elementOne
andelementTwo
do not obey the lexical/syntactic rules for an element name (QName).
回答2:
I believe you can use curly braces instead of <xsl:value-of>
:
<xsl:element name="{name}">
<xsl:value-of select="value"/>
</xsl:element>
回答3:
Didn't try it but this sould work...
<xsl:for-each select="/list/listItem">
<xsl:variable name="elemName" select="name"/>
<xsl:element name="$elemName">
<xsl:value-of select="value"/>
</xsl:element>
</xsl:for-each>
来源:https://stackoverflow.com/questions/4708551/xslvalue-of-used-as-xslelement-name