JavaEar 专注于收集分享传播有价值的技术资料

XSLT for XML Filtering the repeating group

I have the input XML as

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document>
<item>
<functionalName lang="en">Filte</functionalName>
<functionalName lang="hin">test1</functionalName>
<functionalName lang="chi">Filters2</functionalName>
<functionalName lang="hin">Filters3</functionalName>
</item>
<item>
<functionalName lang="en">Filte</functionalName>
<functionalName lang="chi">Filters</functionalName>
<functionalName lang="en">Filters1</functionalName>
</item>

And the desired output after parsing through the XSLT is mentioned below XSLT is mentioned at the end of the query Output XML:

<?xml version="1.0" encoding="UTF-8"?>
<CatalogItem>
<RelationshipData>
    <Relationship>
        <RelationType>Descriptions_for_Item</RelationType>
        <RelatedItems count="3">
            <RelatedItem1 referenceKey="ITEM_DESCRIPTION-functionalName-en" />
            <RelatedItem1 referenceKey="ITEM_DESCRIPTION-functionalName-hin" />
            <RelatedItem1 referenceKey="ITEM_DESCRIPTION-functionalName-chi" />
        </RelatedItems>
    </Relationship>
</RelationshipData>
<RelationshipData>
    <Relationship>
        <RelationType>Descriptions_for_Item</RelationType>
        <RelatedItems count="2">
            <RelatedItem1 referenceKey="ITEM_DESCRIPTION-functionalName-en" />
            <RelatedItem1 referenceKey="ITEM_DESCRIPTION-functionalName-chi" />
        </RelatedItems>
    </Relationship>
</RelationshipData>

XSLT which I am using is not giving me the desired response. Please help

<xsl:output method="xml" indent="yes" />

<xsl:key name="functional" match="functionalName" use="@lang" />  

<xsl:template match="document"> 
    <CatalogItem>
        <xsl:for-each select="item">
            <RelationshipData>
                <Relationship>
                    <RelationType>Descriptions_for_Item</RelationType>

                    <RelatedItems>
                        <xsl:attribute name="count">
                            <xsl:value-of select="count(functionalName[generate-id(.)=generate-id(key('functional',@lang)[1])])"/>          
                        </xsl:attribute>
                        <xsl:apply-templates select="functionalName[generate-id(.)=generate-id(key('functional',@lang)[1])]"/>  
                    </RelatedItems> 
                </Relationship>
            </RelationshipData>
        </xsl:for-each>
    </CatalogItem>
</xsl:template> 


<xsl:template match="functionalName">
    <xsl:for-each value="{@lang}">  
        <xsl:variable name="language" select="../@lang" />              
        <RelatedItem1>
            <xsl:attribute name="referenceKey">
                <xsl:value-of select="concat('ITEM_DESCRIPTION','-','functionalName','-',../@lang)"/>
            </xsl:attribute>
        </RelatedItem1>
    </xsl:for-each>
</xsl:template> 

1个回答

    最佳答案
  1. Change your key from

    <xsl:key name="functional" match="functionalName" use="@lang" />
    

    to

    <xsl:key name="functional" match="functionalName" use="concat(generate-id(..), '|', @lang)" />  
    

    then you can use

    <RelatedItems count="{count(functionalName[generate-id() = generate-id(key('functional', concat(generate-id(..), '|', @lang))[1])])}">
    

    and

    <xsl:apply-templates select="functionalName[generate-id() = generate-id(key('functional', concat(generate-id(..), '|', @lang))[1])]"/> 
    

    and finally you can simplify the template for functionaName to

    <xsl:template match="functionalName">              
            <RelatedItem1 referenceKey="{concat('ITEM_DESCRIPTION','-','functionalName','-', @lang)}"/>
    </xsl:template> 
    

    So the complete samples is

    <xsl:stylesheet 
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes"/>
    
    <xsl:key name="functional" match="functionalName" use="concat(generate-id(..), '|', @lang)" />  
    
    <xsl:template match="document"> 
        <CatalogItem>
            <xsl:for-each select="item">
                <RelationshipData>
                    <Relationship>
                        <RelationType>Descriptions_for_Item</RelationType>
                           <RelatedItems count="{count(functionalName[generate-id() = generate-id(key('functional', concat(generate-id(..), '|', @lang))[1])])}">
                              <xsl:apply-templates select="functionalName[generate-id() = generate-id(key('functional', concat(generate-id(..), '|', @lang))[1])]"/> 
                           </RelatedItems>
                    </Relationship>
                </RelationshipData>
            </xsl:for-each>
        </CatalogItem>
    </xsl:template> 
    
    
    <xsl:template match="functionalName">              
            <RelatedItem1 referenceKey="{concat('ITEM_DESCRIPTION','-','functionalName','-', @lang)}"/>
    </xsl:template>
    
    </xsl:stylesheet>