我一直在努力解决这个问题,我希望你能提供帮助。我自己尝试了很多方法,并搜索了这个网站和其他人,但找不到合适的答案。非常感谢提前。
我想获取输入XML文档并输出具有这些更改的类似副本:
我尝试使用http://exslt.org/common节点集函数以及节点集作为xslt 2.0中的变量但是丢失了。
示例输入,假定行按类型排序。
<fruits>
<fruit>
<row>1</row>
<type> Apple </type>
<name> Gala </name>
<color> Red </color>
<country> US </country>
</fruit>
<fruit>
<row>2</row>
<type> Apple </type>
<name> Fuji </name>
<color> Red </color>
<country> US </country>
</fruit>
<fruit>
<row>3</row>
<type> Apple </type>
<name> Golden Delcious </name>
<color> Yellow </color>
<country> US </country>
</fruit>
<fruit>
<row>4</row>
<type> Orange </type>
<name> Clementine </name>
<color> Orange </color>
<country> US </country>
</fruit>
<fruit>
<row>5</row>
<type> Orange </type>
<name> Sunburst </name>
<color> Orange </color>
<country> US </country>
</fruit>
</fruits>
这是示例输出。对于按类型划分的每组行,请以相同格式在该类型行上方添加标题行。名称和颜色应该在标题行中排除,行值应该有一个&#39; H&#39;前置它,否则它与下一个常规行相同。在以下相同类型的常规行中,应该将该国家排除在外。
<fruits>
<fruit>
<row>H1</row>
<type> Apple </type>
<name> </name>
<color> </color>
<country> US </country>
</fruit>
<fruit>
<row>1</row>
<type> Apple </type>
<name> Gala </name>
<color> Red </color>
<country> </country>
</fruit>
<fruit>
<row>2</row>
<type> Apple </type>
<name> Fuji </name>
<color> Red </color>
<country> </country>
</fruit>
<fruit>
<row>3</row>
<type> Apple </type>
<name> Golden Delcious </name>
<color> Yellow </color>
<country> </country>
</fruit>
<fruit>
<row>H4</row>
<type> Orange </type>
<name> </name>
<color> </color>
<country> US </country>
</fruit>
<fruit>
<row>4</row>
<type> Orange </type>
<name> Clementine </name>
<color> Orange </color>
<country> </country>
</fruit>
<fruit>
<row>5</row>
<type> Orange </type>
<name> Sunburst </name>
<color> Orange </color>
<country> </country>
</fruit>
</fruits>
这是我尝试过的XSLT的一部分。我首先进行了身份转换,并且每次类型更改时都成功创建了一个额外的标题行。但是,我不知道如何操纵标题或常规行来获得所需的输出。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- create the extra header row every time the type changes -->
<xsl:template match="fruit">
<xsl:choose>
<xsl:when test="type != preceding-sibling::*[1]/type">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:when>
<!-- create the header row for the first row where preceding sibling is null -->
<xsl:when test="row = 1">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
xslt 1.0中的解决方案将是首选,但2.0也可以。
非常感谢你!
答案 0 :(得分:1)
我会相应地编辑答案,但是,你的意思是这样吗?
(这里我只改变&#34;行&#34;节点为例)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row">
<xsl:copy>H<xsl:value-of select="."/></xsl:copy>
</xsl:template>
<!-- create the extra header row every time the type changes -->
<xsl:template match="fruit">
<xsl:choose>
<xsl:when test="type != preceding-sibling::*[1]/type">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:when>
<!-- create the header row for the first row where preceding sibling is null -->
<xsl:when test="row = 1">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
在XSLT 2.0中,这是
<xsl:template match="fruits">
<fruits>
<xsl:for-each-group select="fruit" group-adjacent="type">
<xsl:copy>
<row>H<xsl:value-of select="row"/></row>
<type><xsl:value-of select="type"/></type>
<name/>
<color/>
<country><xsl:value-of select="country"/></country>
</xsl:copy>
<xsl:copy-of select="current-group()"/>
</xsl:for-each-group>
</fruits>
</xsl:template>
答案 2 :(得分:0)
我会相应地修改答案 -
XSLT脚本代码:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fruit">
<xsl:variable name="type" select="child::type"/>
<xsl:choose>
<xsl:when test="preceding-sibling::*[1][type != $type] or (count(preceding-sibling::fruit) = 0)">
<fruit>
<row>
<xsl:value-of select="concat('H', row)"/>
</row>
<type> <xsl:value-of select="type"/></type>
<name> </name>
<color> </color>
<country> <xsl:value-of select="country"/> </country>
</fruit>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XSLT脚本生成的输出:
<?xml version="1.0" encoding="UTF-8"?>
<fruits>
<fruit>
<row>H1</row>
<type> Apple </type>
<name/>
<color/>
<country> US </country>
</fruit>
<fruit>
<row>1</row>
<type> Apple </type>
<name> Gala </name>
<color> Red </color>
<country> US </country>
</fruit>
<fruit>
<row>2</row>
<type> Apple </type>
<name> Fuji </name>
<color> Red </color>
<country> US </country>
</fruit>
<fruit>
<row>3</row>
<type> Apple </type>
<name> Golden Delcious </name>
<color> Yellow </color>
<country> US </country>
</fruit>
<fruit>
<row>H4</row>
<type> Orange </type>
<name/>
<color/>
<country> US </country>
</fruit>
<fruit>
<row>4</row>
<type> Orange </type>
<name> Clementine </name>
<color> Orange </color>
<country> US </country>
</fruit>
<fruit>
<row>5</row>
<type> Orange </type>
<name> Sunburst </name>
<color> Orange </color>
<country> US </country>
</fruit>
</fruits>
答案 3 :(得分:0)
以下是在XSLT 2.0版中处理问题的另一种方法:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fruits">
<fruits>
<xsl:for-each-group select="fruit" group-by="type">
<fruit>
<row>
<xsl:value-of select="concat('H', current-group()[1]//row)"></xsl:value-of>
</row>
<type> <xsl:value-of select="current-group()[1]//type"/></type>
<name> </name>
<color> </color>
<country> <xsl:value-of select="current-group()[1]//country"/> </country>
</fruit>
<xsl:copy-of select="current-group()"/>
</xsl:for-each-group>
</fruits>
</xsl:template>
</xsl:stylesheet>