【问题标题】:XSLT unable to group/sort nodes based on valueXSLT 无法根据值对节点进行分组/排序
【发布时间】:2011-07-16 19:44:09
【问题描述】:

我正在尝试转换此 xml。但是我遇到了格式问题。有人可以指导我解决这个问题。提前致谢

<?xml version="1.0" encoding="windows-1252"?>
<XML>
    <Attributes>
        <Attribute>
            <id>5</id>
            <Name>Buyer ID</Name>
            <Type>common</Type>
            <Value>Lee</Value>
        </Attribute>
        <Attribute>
            <id>331</id>
            <Name>Enviornment</Name>
            <Type>common</Type>
            <Value>Development</Value>
        </Attribute>
        <Attribute>
            <id>79</id>
            <Name>Retail</Name>
            <Type>common</Type>
            <Value></Value>
        </Attribute>
        <Attribute>
            <id>402</id>
            <Name>Gender</Name>
            <Type>category</Type>
            <Value>Men</Value>
        </Attribute>
        <Attribute>
            <id>433</id>
            <Name>HeelHeight</Name>
            <Type>category</Type>
            <Value></Value>
        </Attribute>
        <Attribute>
            <id>41</id>
            <Name>PlusShip</Name>
            <Type>common</Type>
            <Value>False</Value>
            <Path></Path>
        </Attribute>
    </Attributes>
</XML>

进入以下 XML。有人可以给我一些提示,告诉我如何根据 Attributes/Attribute/Type 的值转换这个 xml

<?xml version="1.0" encoding="utf-8" ?>
<Data Schema="XML A">
  <Attributes type="Common">
    <Attr id="" name="Buyer ID" value="Lee" />
    <Attr id="" name="Enviornment" value="Development" />
    <Attr id="" name="Retail" value="" />
    <Attr id="" name="PlusShip" value="False" />
 </Attributes>
 <Attributes type="Category">
   <Attr id="" name="Gender" value="Men" />
   <Attr id="" name="HeelHeight" value="" />
 </Attributes>

【问题讨论】:

    标签: xslt sorting formatting grouping


    【解决方案1】:

    以下样式表会产生所需的结果:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <Data Schema="XML A">
                <xsl:apply-templates/>
            </Data>
        </xsl:template>
        <xsl:template match="Attribute[not(Type=following::Type)]">
            <Attributes type="{Type}">
                <xsl:for-each select="../Attribute[Type=current()/Type]">
                   <Attr id="{id}" name="{Name}" value="{Value}"/>
                </xsl:for-each>
            </Attributes>
        </xsl:template>
        <xsl:template match="Attribute"/>
    </xsl:stylesheet>
    

    源文档的输出:

    <Data Schema="XML A">
        <Attributes type="category">
            <Attr id="402" name="Gender" value="Men"/>
            <Attr id="433" name="HeelHeight" value=""/>
        </Attributes>
        <Attributes type="common">
            <Attr id="5" name="Buyer ID" value="Lee"/>
            <Attr id="331" name="Enviornment" value="Development"/>
            <Attr id="79" name="Retail" value=""/>
            <Attr id="41" name="PlusShip" value="False"/>
        </Attributes>
    </Data>
    

    编辑:好的,让我们摆脱那个丑陋的for-each

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
            <Data Schema="XML A">
                <xsl:apply-templates/>
            </Data>
        </xsl:template>
        <xsl:template match="Attribute[not(Type=following::Type)]">
            <Attributes type="{Type}">
                <xsl:apply-templates 
                     select="../Attribute[Type=current()/Type]" mode="out"/>
            </Attributes>
        </xsl:template>
        <xsl:template match="Attribute" mode="out">
            <Attr id="{id}" name="{Name}" value="{Value}"/>
        </xsl:template>
        <xsl:template match="Attribute"/>
    </xsl:stylesheet>
    

    我感觉好多了。

    编辑 #2: 使用 Muenchian 方法(带排序):

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:key name="type" match="Attribute" use="Type"/>
        <xsl:template match="/">
            <Data Schema="XML A">
                <xsl:apply-templates select="XML/Attributes/Attribute">
                     <xsl:sort select="Type" order="descending"/>
                </xsl:apply-templates>
            </Data>
        </xsl:template>
        <xsl:template 
                match="Attribute[generate-id()=generate-id(key('type', Type)[1])]">
            <Attributes type="{Type}">
                <xsl:apply-templates 
                        select="../Attribute[Type=current()/Type]" mode="out"/>
            </Attributes>
        </xsl:template>
        <xsl:template match="Attribute" mode="out">
             <Attr id="{id}" name="{Name}" value="{Value}"/>
        </xsl:template>
        <xsl:template match="Attribute"/>
    </xsl:stylesheet>
    

    产生以下(有序)输出:

    <Data Schema="XML A">
        <Attributes type="common">
            <Attr id="5" name="Buyer ID" value="Lee"/>
            <Attr id="331" name="Enviornment" value="Development"/>
            <Attr id="79" name="Retail" value=""/>
            <Attr id="41" name="PlusShip" value="False"/>
        </Attributes>
        <Attributes type="category">
            <Attr id="402" name="Gender" value="Men"/>
            <Attr id="433" name="HeelHeight" value=""/>
       </Attributes>
    </Data>
    

    【讨论】:

    • 还有一个问题。我如何排序,我将得到第一个 而不是 。我尝试使用以下 xsl:sort 但它不起作用。 任何想法...
    • @lwburk:确实正确。但是用 Muenchian 方法与旧的“我没有前面的平等”而不是“我是同类中的第一个”分组?
    • @Alejandro - 我知道。可耻。
    • @Alejandro - 添加了对 Muenchian 方法的尝试。
    • @user662877 - 查看我的最新编辑,它增加了排序(也可能更快一点)。
    猜你喜欢
    • 2017-09-02
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    相关资源
    最近更新 更多