2010-08-11 160 views
1

此問題與此帖子相關Find maximum value of all child elements and get its parent element in XSLT。我錯誤地問了我的問題。其實我需要的輸出有點不同。我需要將網站節點ID與工地節點進行匹配,並找出爲該網站工作的時間更長的人。查找所有子元素的最大值並獲取其父元素xslt

<root> 
    <Site id="S1"> 
     <othernodes></othernodes> 
    </Site> 
    <Site id="S2"> 
     <othernodes></othernodes> 
    </Site> 
    <Site id="S3"> 
     <othernodes></othernodes> 
    </Site> 
    <WorkSite Person="P1" Site="S1"> 
     <Hours>8</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S2"> 
     <Hours>2</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S3"> 
     <Hours>20</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S1"> 
     <Hours>6</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S2"> 
     <Hours>10</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S3"> 
     <Hours>21</Hours> 
    </WorkSite> 
</root> 

轉化的內容應該是這樣的

<root> 
    <site id="S1"> 
      <othernodes></othernodes> 
      <person>P1</person> 
    </site> 
    <site id="S2"> 
      <othernodes></othernodes> 
      <person>P2</person> 
    </site> 
    <site id="S3"> 
      <othernodes></othernodes> 
      <person>P1</person> 
    </site> 
</root> 

別人在幫助呢?

+0

好問題再次(+1)。請參閱我的答案,瞭解一個完整但短小且效率非常高的XSLT 1.0解決方案。 – 2010-08-12 01:19:55

回答

1

像這樣?

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

<xsl:template match="/root/Site"> 
    <xsl:variable name="sid" select="./@id" /> 
    <site id="{./@id}"> 
    <othernodes></othernodes> 
    <xsl:apply-templates select="/root/WorkSite[@Site = $sid]"> 
     <xsl:sort select="./Hours" data-type="number" order="descending"/> 
    </xsl:apply-templates> 
    </site> 
</xsl:template> 

<xsl:template match="/root/WorkSite"> 
    <xsl:if test="position() = 1"> 
    <person><xsl:value-of select="./@Person" /></person> 
    </xsl:if> 
</xsl:template> 
0

這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="BySite" match="WorkSite" use="@Site"/> 
    <xsl:template match="@*|node()" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="Site/*[last()]"> 
     <xsl:call-template name="identity"/> 
     <person> 
      <xsl:value-of select="substring-after(
            key('BySite',../@id) 
             [not(key('BySite',@Site)/Hours 
              > Hours)] 
             /@Person, 
            'P')" /> 
     </person> 
    </xsl:template> 
    <xsl:template match="WorkSite"/> 
</xsl:stylesheet> 

輸出:

<root> 
    <Site id="S1"> 
     <othernodes></othernodes> 
     <person>1</person> 
    </Site> 
    <Site id="S2"> 
     <othernodes></othernodes> 
     <person>2</person> 
    </Site> 
    <Site id="S3"> 
     <othernodes></othernodes> 
     <person>2</person> 
    </Site> 
</root> 
0

這是我會怎麼做。 (我添加了for-each,以防萬一你在一個網站上有多個人的時間完全相同)。

編輯:我沒有在其他帖子中看到XSLT 1.0要求,直到我添加了我的答案。對於那個很抱歉!

XML輸入:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <Site id="S1"> 
    <othernodes/> 
    </Site> 
    <Site id="S2"> 
    <othernodes/> 
    </Site> 
    <Site id="S3"> 
    <othernodes/> 
    </Site> 
    <WorkSite Person="P1" Site="S1"> 
    <Hours>8</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S2"> 
    <Hours>2</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S3"> 
    <Hours>20</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S1"> 
    <Hours>6</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S2"> 
    <Hours>10</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S3"> 
    <Hours>21</Hours> 
    </WorkSite> 
</root> 

XSLT樣式表2.0:

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

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

    <xsl:template match="Site"> 
    <xsl:variable name="vSiteId"> 
     <xsl:value-of select="@id"/> 
    </xsl:variable> 
    <xsl:variable name="vMaxHours"> 
     <xsl:value-of select="max(/root/WorkSite[@Site=$vSiteId]/Hours)"/> 
    </xsl:variable> 
    <site id="{@id}"> 
     <xsl:apply-templates/> 
     <xsl:for-each select="/root/WorkSite[Hours=$vMaxHours]/@Person"> 
     <person> 
      <xsl:value-of select="."/> 
     </person>   
     </xsl:for-each> 
    </site> 
    </xsl:template> 

    <xsl:template match="WorkSite"/> 

</xsl:stylesheet> 

XML輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <site id="S1"> 
     <othernodes/> 
     <person>P1</person> 
    </site> 
    <site id="S2"> 
     <othernodes/> 
     <person>P2</person> 
    </site> 
    <site id="S3"> 
     <othernodes/> 
     <person>P2</person> 
    </site> 
</root> 
1

這XSLT 1.0轉換

<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="kSiteByName" match="@Site" use="."/> 

<xsl:key name="kWorksiteBySite" 
    match="WorkSite" use="@Site"/> 

<xsl:key name="kSiteChildrenBySiteid" 
    match="Site/node()" use="../@id"/> 

<xsl:variable name="vSites" select= 
    "/*/*/@Site[generate-id() 
      = 
       generate-id(key('kSiteByName',.)[1]) 
       ]" 
    /> 

<xsl:template match="/"> 
    <root> 
    <xsl:for-each select="$vSites"> 
     <xsl:for-each select="key('kWorksiteBySite', .)"> 
     <xsl:sort select="Hours" data-type="number" 
     order="descending"/> 
     <xsl:if test="position()=1"> 
     <site id="{@Site}"> 
      <xsl:copy-of select="key('kSiteChildrenBySiteid', @Site)"/> 
      <person><xsl:value-of select="@Person"/></person> 
     </site> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:for-each> 
    </root> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<root> 
    <Site id="S1"> 
     <othernodes></othernodes> 
    </Site> 
    <Site id="S2"> 
     <othernodes></othernodes> 
    </Site> 
    <Site id="S3"> 
     <othernodes></othernodes> 
    </Site> 
    <WorkSite Person="P1" Site="S1"> 
     <Hours>8</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S2"> 
     <Hours>2</Hours> 
    </WorkSite> 
    <WorkSite Person="P1" Site="S3"> 
     <Hours>20</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S1"> 
     <Hours>6</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S2"> 
     <Hours>10</Hours> 
    </WorkSite> 
    <WorkSite Person="P2" Site="S3"> 
     <Hours>21</Hours> 
    </WorkSite> 
</root> 

產生想要的,正確的結果

<root> 
    <site id="S1"> 
     <othernodes/> 
     <person>P1</person> 
    </site> 
    <site id="S2"> 
     <othernodes/> 
     <person>P2</person> 
    </site> 
    <site id="S3"> 
     <othernodes/> 
     <person>P2</person> 
    </site> 
</root> 

待辦事項ñ OTE

  1. 使用了分組找到所有不同 網站值Muenchian方法。

  2. 通過按降序排序並從排序後的節點列表中獲取第一個結果,找到最大值的方法。(O(N * log(N))比多次掃描節點序列(比較每個值與值列表中的每個值)具有O(N^2)時間複雜度更有效得多。

相關問題