6

请帮忙,我是 XSLT 新手,我正在尝试将一种 XML 格式转换为另一种。

我需要提取唯一的属性值并将这些值转换为新格式。下面的示例 XML 显示了原始格式和新/目标格式。

我花了很长时间试图做到这一点而没有任何享受。任何人都可以帮忙或给我一些指示吗?

原始格式:

<base>
  <level>
    <level2 Name ="AA" value="1"/>
  </level>
  <level>
    <level2 Name ="BB" value="2"/>
  </level>
  <level>
    <level2 Name ="BB" value="3"/>
  </level>
  <level>
    <level2 Name ="CC" value="4"/>
  </level>
  <level>
    <level2 Name ="AA" value="5"/>
  </level>
</base>

新格式:

<base>
  <levelNames>
    <level level2Name ="AA"/>
    <level level2Name ="BB"/>
    <level level2Name ="CC"/>
  </levelNames>
</base>

非常感谢。

4

3 回答 3

11

XSLT 解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="LevelDistint" match="level2" use="@Name"/>
    <xsl:template match="base">
        <base>
            <levelNames>
                <xsl:for-each select="level/level2[generate-id() = generate-id(key('LevelDistint', @Name)[1])]">
                    <level>
                        <xsl:attribute name="level2Name"><xsl:value-of select="normalize-space(@Name)"/></xsl:attribute>
                    </level>
                </xsl:for-each>
            </levelNames>
        </base>
    </xsl:template>
</xsl:stylesheet>

XSLT 输出:

<?xml version="1.0" encoding="UTF-8"?>
<base>
    <levelNames>
        <level level2Name="AA"/>
        <level level2Name="BB"/>
        <level level2Name="CC"/>
    </levelNames>
</base>
于 2009-07-03T10:40:08.293 回答
2

Once again the Muenchian grouping technique appears to be the missing piece.

Fairly trivial problem for it, so I'll let you do your own work to get to grips with Muench.

于 2009-07-02T10:55:03.323 回答
0

请先创建 xsl:key 然后您可以轻松使用以下代码。

xsl:键名=“级别名称”匹配=“级别2”使用=“@名称”

<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="base">
    <xsl:element name="{local-name(.)}">
        <xsl:element name="levelNames">
           <xsl:apply-templates/>
        </xsl:element>
    </xsl:element>
</xsl:template>

    <xsl:template match="level">
        <xsl:for-each select="level2[count(.|key('levelName', @Name)[1]) = 1]">
            <xsl:sort order="ascending" data-type="text" select="@Name"/>
            <xsl:element name="{local-name(..)}">
                <xsl:attribute name="level2Name">
                    <xsl:value-of select="@Name"/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>
于 2009-07-02T14:09:45.317 回答