什么是将转换的XSLT 2.0样式表
<paramList>
<param name="y" out="true"/>
<param name="y" in="true"/>
<param name="z" out="true"/>
<param name="x" in="true"/>
</paramList>
到
<paramList>
<param name="x" in="true" />
<param name="y" in="true" out="true"/>
<param name="z" out="true"/>
</paramList>
在结果中,“in,only”参数位于“in&amp; out”参数之前,而“in&amp; out”参数又位于“out,only”参数之前。此外,两个“y”元素已合并为一个。
答案 0 :(得分:0)
<?xml version="1.0" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/paramList">
<xsl:copy>
<xsl:for-each-group select="param" group-by="@name">
<xsl:sort select="current-group()/@in" order="descending"/>
<xsl:sort select="current-group()/@out"/>
<param name="{current-grouping-key()}">
<xsl:for-each select="current-group()/@*">
<xsl:copy/>
</xsl:for-each>
</param>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
以防有人需要在XSLT 1中执行此操作:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="paramsByName" match="param" use="@name"/>
<xsl:template match="/paramList">
<xsl:copy>
<xsl:for-each select="param[count(. | key('paramsByName', @name)[1]) = 1]">
<xsl:sort select="@name"/>
<xsl:copy>
<xsl:for-each select="key('paramsByName', @name)">
<xsl:copy-of select="@*"/>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这使用Munchian grouping,因为XSLT 1没有分组构造。
修改强>
显然也可以只复制in和out属性,在这种情况下,以下样式表完成工作(也遵循Dimetre的建议:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="paramsByName" match="param" use="@name"/>
<xsl:template match="/paramList">
<xsl:copy>
<xsl:for-each select="param[count(. | key('paramsByName', @name)[1]) = 1]">
<xsl:sort select="@name"/>
<xsl:copy-of select="key('paramsByName', @name)/@*[local-name() = 'in' or local-name() = 'out']"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
一个小改进:
在@ Nick-Jones和@Obalix的解决方案中,写的时间更短:
<xsl:copy-of select="current-group()/@*"/>
或强>
<xsl:copy-of select="key('paramsByName', @name)/@*"/>
分别:
<xsl:for-each select="current-group()/@*">
<xsl:copy/>
</xsl:for-each>
或强>
<xsl:for-each select="key('paramsByName', @name)">
<xsl:copy-of select="@*"/>
</xsl:for-each>
答案 3 :(得分:0)
如果输入文档中有多个paramList
元素,Obalix的答案可能不起作用。如果文档描述的软件界面中有多个程序,每个程序都有paramList
,我认为这可能会引起海报的兴趣。
以下是输入示例:
<root>
<func name="one">
<paramList>
<param name="y" out="true"/>
<param name="y" in="true"/>
<param name="z" out="true"/>
<param name="x" in="true"/>
</paramList>
</func>
<func name="two">
<paramList>
<param name="z" in="true"/>
</paramList>
</func>
</root>
这是我提出的样式表,建立在Obalix的答案之上。诀窍是使用包含paramList
元素ID的本地密钥ID。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:key name="paramsByName" match="param" use="concat(generate-id(..), '/', @name)"/>
<xsl:template match="paramList">
<xsl:copy>
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:for-each select="param[count(. | key('paramsByName', concat($id, '/', @name))[1]) = 1]">
<xsl:copy>
<xsl:copy-of select="key('paramsByName', concat($id, '/', @name))/@*"/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>