如何将特定属性转换为元素

时间:2012-01-03 10:03:42

标签: xml xslt

我需要将特定的XML属性转换为XML元素。 输入XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<filter query="select" name="some name"/>

我的愿望输出如下:

<?xml version="1.0" encoding="UTF-8"?>
    <filter name="some name">
    <query>select</query>
</filter>

我正在使用以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"      xmlns="http://www.w3.org/1999/xhtml">
   <xsl:strip-space elements="*"/>
   <xsl:output indent="yes"/>

   <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
   </xsl:template>

   <xsl:template match="/filter/@query">
        <xsl:element name="{name(.)}">
            <xsl:value-of select="."/>
        </xsl:element>
   </xsl:template>
</xsl:stylesheet>

但是,当我将XSLT应用于提供的示例时,name属性将消失:

<?xml version="1.0" encoding="UTF-8"?>
<filter>
    <query>select</query>
</filter>

如果我改变了属性排序,即在'query'之前输入'name',一切都很完美。 我尝试解决它,但我的XSLT知识非常有限。请帮忙。提前致谢。

2 个答案:

答案 0 :(得分:2)

这应该为您提供所需的输出:

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:strip-space elements="*"/>
   <xsl:output indent="yes"/>

   <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
   </xsl:template>

   <!-- match the filter element -->
   <xsl:template match="filter">
     <!-- output a filter element -->
     <xsl:element name="filter">
       <!-- add the name attribute, using the source name attribute value -->
       <xsl:attribute name="name">
         <xsl:value-of select="@name"/>
       </xsl:attribute>
       <!-- add the query child element, using the source query attribute value -->
       <xsl:element name="query">
         <xsl:value-of select="@query"/>
       </xsl:element>
     </xsl:element>
   </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

这可能会更短:

<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="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*[not(name()='query')]"/>
     <query><xsl:value-of select="@query"/></query>
     </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<filter query="select" name="some name"/>

生成所需的正确输出:

<filter name="some name">
   <query>select</query>
</filter>