使用XSLT按新XML中的属性对元素进行分组

时间:2017-05-27 12:25:29

标签: xml xslt

下午好!

有这个xml片段:

    <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="trasnf.xsl"?>
<Shapes xmlns="namespaceProject"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="namespaceProject validator.xsd">
    <Shape id="id1">
            <Type>Square</Type>
            <Data>
                <Color>Red</Color>
            </Data>
        </Shape>
    <Shape id="id2">
            <Type>Circle</Type>
            <Data>
                <Color>Blue</Color>
            </Data>
        </Shape>
    <Shape id="id3">
            <Type>Triangle</Type>
            <Data>
                <Color>Red</Color>
            </Data>
        </Shape>
<Shapes>

希望XML输出如下:

<Shapes>
    <Color name="Red">
            <Type>Square</Type>
            <Type>Triangle</Type>
    </Color>
    <Color name="Blue">
            <Type>Circle</Type>
    </Color>
<Shapes>

我怎样才能在XSLT中做到这一点? 这是我从互联网上和其他用户的问题中读到的内容,但它仍然无法正确打印。它只是通过将xml拖到浏览器(尝试过Internet Explorer和Firefox)来输出文本而不是标签。

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

<xsl:template match="/">
<Shapes>
        <xsl:apply-templates select="/p:Shapes/p:Shape/p:Data/p:Color[not(. = ../../preceding-sibling::p:Data/p:Color)]"/>
</Shapes>
</xsl:template>

<xsl:template match="p:Color">
    <xsl:element name="Color">
        <xsl:attribute name="name">
            <xsl:value-of select="."/>
        </xsl:attribute>
        <xsl:for-each select="/p:Shapes/p:Shape[p:Data/p:Color = current()]">
            <xsl:element name="Type">
                <xsl:value-of select="p:Type"/>
            </xsl:element>
      </xsl:for-each>
    </xsl:element>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

您可以将apply-templates更正为<xsl:apply-templates select="/p:Shapes/p:Shape/p:Data/p:Color[not(. = ../../preceding-sibling::p:Shape/p:Data/p:Color)]"/>以修复您的代码。但请注意,在XSLT 2.0中使用xsl:for-each-grouphttps://www.w3.org/TR/xslt20/#grouping-examples)或在XSLT 1.0中使用Muenchian grouping可以更轻松,更高效地进行分组。您不需要计算名称的结果元素可以简单地创建为文字,如<Type>...</Type>而不是<xsl:element name="Type">...</xsl:element>