开发者

XSLT unable to group/sort nodes based on value

开发者 https://www.devze.com 2023-02-18 10:19 出处:网络
I\'m trying to transform this xml. However I\'m having formatting issues. Could someone please guide me to solve this problem.Thanks in advance

I'm trying to transform this xml. However I'm having formatting issues. Could someone please guide me to solve this problem. Thanks in advance

<?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>开发者_Python百科;PlusShip</Name>
            <Type>common</Type>
            <Value>False</Value>
            <Path></Path>
        </Attribute>
    </Attributes>
</XML>

Into the following XML. Could someone please give me some tips in how to transform this xml based on the value of Attributes/Attribute/Type

<?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>


The following stylesheet produces the desired result:

<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>

Output on your source document:

<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>

Edit: OK, let's get rid of that ugly 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>

I feel much better.

Edit #2: Using the Muenchian Method (with sorting):

<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>

Produces the following (ordered) output:

<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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号