2013-04-02 25 views
2

我需要一個xsl,它可以從任何「object_name」中獲取「item_revision_id」的最大值。 從這個輸入........xslt挑選組中的最大值

<rows> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="description">description of version 00</row_element> 
     <row_element property_name="item_revision_id">00</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="description">description of version 01</row_element> 
     <row_element property_name="item_revision_id">01</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="description">description of version 02</row_element> 
     <row_element property_name="item_revision_id">02</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="description">description of version 00</row_element> 
     <row_element property_name="item_revision_id">00</row_element> 
    </row> 
</rows> 

所需的輸出是

<?xml version="1.0" encoding="Windows-1252"?> 
    <rows> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="description">description of version 01</row_element> 
     <row_element property_name="item_revision_id">01</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="description">description of version 02</row_element> 
     <row_element property_name="item_revision_id">02</row_element> 
    </row> 
</rows> 

我想要得到的最大行元素不是創建一個新的混合值

<?xml version="1.0" encoding="Windows-1252"?> 
<rows> 
    <row><!-- this is right --> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="description">description of version 01</row_element> 
     <row_element property_name="item_revision_id">01</row_element> 
    </row> 
    <row><!-- this is wrong --> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="description">description of version 00</row_element> 
     <row_element property_name="item_revision_id">02</row_element> 
    </row> 
</rows> 

有幫助嗎?

回答

1

這種轉變

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kRowByObjName" match="row" use="*[@property_name='object_name']"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
"row[not(generate-id() 
     = 
      generate-id(key('kRowByObjName', *[@property_name='object_name'])[1]) 
     )]"/> 

<xsl:template match="*[@property_name='item_revision_id']/text()"> 
    <xsl:for-each select="key('kRowByObjName', ../../*[@property_name='object_name'])"> 
    <xsl:sort select="*[@property_name='item_revision_id']" 
      data-type="number" order="descending"/> 
    <xsl:if test="position()=1"> 
    <xsl:value-of select="*[@property_name='item_revision_id']"/> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<rows> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="item_revision_id">00</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="item_revision_id">01</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="item_revision_id">02</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="item_revision_id">00</row_element> 
    </row> 
</rows> 

產生想要的,正確的結果

<rows> 
    <row> 
     <row_element property_name="object_name">pluto</row_element> 
     <row_element property_name="item_revision_id">01</row_element> 
    </row> 
    <row> 
     <row_element property_name="object_name">pippo</row_element> 
     <row_element property_name="item_revision_id">02</row_element> 
    </row> 
</rows> 

二, XSLT 2.0解決方案

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kRowByObjName" match="row" use="*[@property_name='object_name']"/> 

<xsl:template match="/*"> 
    <rows> 
    <xsl:for-each-group select="row" group-by="*[@property_name='object_name']"> 
     <row> 
     <xsl:sequence select="*[@property_name='object_name']"/> 
     <xsl:sequence select= 
     "current-group() 
      /*[@property_name='item_revision_id' 
      and 
      . = max(current-group()/*[@property_name='item_revision_id']/number()) 
      ]"/> 
     </row> 
    </xsl:for-each-group> 
    </rows> 
</xsl:template> 
</xsl:stylesheet> 
+0

偉大的答案謝謝。 – user2217858

+0

我看到一個副作用,說明我沒有做出正確的問題..: – user2217858

+0

我看到一個副作用,這解釋了我沒有做出正確的問題..:我確實想要「選擇」具有最高「」 item_revision_id「。如果我有另一個row_element與property_name = descritption我證實,在結果有時不會複製來自最新修訂的一個。我該如何應對? – user2217858