2013-03-18 50 views
1

我有一個XML如下。對於每個測試,我需要對貓和標題和組進行分類。 對於我需要獲得標題和設置值的cat值abc。 任何設置值都與按照升序順序在設置節點內添加標題值的需求相匹配。在這裏我做了硬編碼的貓值。但在我的情況下,貓的價值是從外部來源。爲每個和排序和組xml使用xslt

<?xml version="1.0" encoding="utf-8" ?> 
<compound> 
    <test> 
    <title>k</title> 
    <cetval> 
     <cat>abc</cat> 
     <cat>fcg</cat> 
    </cetval> 
    <value>1</value> 
    <set> 
     <color>blue</color> 
    </set> 
    </test> 
    <test> 
    <title>p</title> 
    <cetval> 
     <cat>fcg</cat> 
     <cat>klm</cat> 
    </cetval> 

    <value>10</value> 
    <set> 
     <color>pink</color> 
    </set> 
    </test> 
    <test> 
    <title>j</title> 
    <cetval> 
     <cat>fcg</cat> 
     <cat>klm</cat> 
     <cat>abc</cat> 
    </cetval> 
    <value>484</value> 
    <set> 
     <color>yellow</color> 
    </set> 
    </test> 
    <test> 
    <title>v</title> 
    <cetval> 
     <cat>dji</cat> 
     <cat>kfjsdlk</cat> 
    </cetval> 
    <value>93</value> 

    </test> 
    <test> 
    <title>r</title> 
    <cetval> 
     <cat>deiu</cat> 
     <cat>kfjdf</cat> 
     <cat>abc</cat> 
    </cetval> 
    <value>10</value> 
    <set> 
     <color>blue</color> 
    </set> 
    <test> 
     <title>i</title> 
     <cetval> 
     <cat>fcg</cat> 
     <cat>klm</cat> 
     <cat>abc</cat> 
     </cetval> 

     <value>10</value> 

    </test> 
    <test> 
     <title>w</title> 
     <cetval> 
     <cat>diweif</cat> 
     <cat>fjf</cat> 
     <cat>abc</cat> 
     </cetval> 
     <value>10</value> 
     <set> 
     <color>yellow</color> 
     </set> 
    </test> 
    </test> 

</compound>  

我需要的輸出如下:

<?xml version="1.0" encoding="utf-8" ?> 
<compound> 
    <cat>abc</cat> 
    <set> 
    <color>blue</color> 
    <title>k</title> 
    <title>r</title> 
    </set> 
    <set> 
    <color>yellow</color> 
    <title>j</title> 
    <title>w</title> 
    </set> 
    <title>i</title> 


</compound> 

我變換看起來象下面這樣:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:for-each select="compound/test"> 
     <xsl:sort select="./cetval/cat" order="ascending"/> 
     <xsl:sort select="./title" order="ascending"/> 
     <xsl:for-each select="./cetval/cat"> 
      <xsl:choose> 
      <xsl:when test="./cat = 'abc' > 0"> 

       <xsl:value-of select="ancestor::test/title"/> 

      </xsl:when> 
      </xsl:choose> 
     </xsl:for-each> 

     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

任何一個可以建議我如何生成所需的輸出?

+0

Shouldn' t「藍」有標題「k」和「r」,而不是「k」和「p」? – 2013-03-18 19:58:42

+0

Tim,我編輯了我的輸出.. – Blossom 2013-03-18 20:02:21

+0

選擇' i'的標準是什麼? – JLRishe 2013-03-18 20:13:07

回答

2

好的,我想我已經明白了你的要求。這個怎麼樣:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> 
    <xsl:key name="kColor" match="test" use="set/color" /> 
    <xsl:param name="catValue" select="'abc'" /> 

    <xsl:template match="/*"> 
    <xsl:copy> 
     <cat> 
     <xsl:value-of select ="$catValue"/> 
     </cat> 
     <xsl:apply-templates 
     select="//test[generate-id() = 
         generate-id(
          key('kColor', set/color) 
            [cetval/cat = $catValue][1] 
           ) 
         ]" /> 
     <xsl:apply-templates 
     select="//test[cetval/cat = $catValue and not(set/color)] 
         /title"> 
     <xsl:sort select="."/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="test"> 
    <set> 
     <xsl:apply-templates select="set/color" /> 
     <xsl:apply-templates 
     select="key('kColor', set/color)[cetval/cat = $catValue]/title"> 
     <xsl:sort select="." /> 
     </xsl:apply-templates> 
    </set> 
    </xsl:template> 

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

這裏$catValue被指定爲參數,這樣你就可以從外部傳遞不同的值。當這是在您的示例XML運行,其結果是:

<compound> 
    <cat>abc</cat> 
    <set> 
    <color>blue</color> 
    <title>k</title> 
    <title>r</title> 
    </set> 
    <set> 
    <color>yellow</color> 
    <title>j</title> 
    <title>w</title> 
    </set> 
    <title>i</title> 
</compound> 
+0

這是一個了不起的xslt :) - 非常感謝你! – Blossom 2013-03-18 21:12:55

+0

@ user1490088:將其標記爲正確答案(點擊答案左側的複選標記) – MiMo 2013-03-19 01:20:54

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="kTestByCat" match="test" use="cetval/cat"/> 
<xsl:key name="kTestByColor" match="test[cetval/cat='abc']" 
     use="set/color"/> 

<xsl:template match="/"> 
    <compound> 
    <cat>abc</cat> 
     <xsl:apply-templates select= 
     "/*/*[generate-id() 
      = 
      generate-id(key('kTestByColor',set/color)[1])]"/> 
    </compound> 
</xsl:template> 

<xsl:template match="test"> 
    <set> 
    <color><xsl:value-of select="set/color"/></color> 
    <xsl:copy-of select="key('kTestByColor',set/color)/title"/> 
    </set> 
</xsl:template> 
</xsl:stylesheet> 

當這種變換所提供的XML文檔應用:

<compound> 
    <test> 
     <title>k</title> 
     <cetval> 
      <cat>abc</cat> 
      <cat>fcg</cat> 
     </cetval> 
     <value>1</value> 
     <set> 
      <color>blue</color> 
     </set> 
    </test> 
    <test> 
     <title>p</title> 
     <cetval> 
      <cat>fcg</cat> 
      <cat>klm</cat> 
     </cetval> 
     <value>10</value> 
     <set> 
      <color>pink</color> 
     </set> 
    </test> 
    <test> 
     <title>j</title> 
     <cetval> 
      <cat>fcg</cat> 
      <cat>klm</cat> 
      <cat>abc</cat> 
     </cetval> 
     <value>484</value> 
     <set> 
      <color>yellow</color> 
     </set> 
    </test> 
    <test> 
     <title>v</title> 
     <cetval> 
      <cat>dji</cat> 
      <cat>kfjsdlk</cat> 
     </cetval> 
     <value>93</value> 
    </test> 
    <test> 
     <title>r</title> 
     <cetval> 
      <cat>deiu</cat> 
      <cat>kfjdf</cat> 
      <cat>abc</cat> 
     </cetval> 
     <value>10</value> 
     <set> 
      <color>blue</color> 
     </set> 
     <test> 
      <title>i</title> 
      <cetval> 
       <cat>fcg</cat> 
       <cat>klm</cat> 
       <cat>abc</cat> 
      </cetval> 
      <value>10</value> 
     </test> 
     <test> 
      <title>w</title> 
      <cetval> 
       <cat>diweif</cat> 
       <cat>fjf</cat> 
       <cat>abc</cat> 
      </cetval> 
      <value>10</value> 
      <set> 
       <color>yellow</color> 
      </set> 
     </test> 
    </test> 
</compound> 

想要的,正確的結果產生:

<compound> 
    <cat>abc</cat> 
    <set> 
     <color>blue</color> 
     <title>k</title> 
     <title>r</title> 
    </set> 
    <set> 
     <color>yellow</color> 
     <title>j</title> 
     <title>w</title> 
    </set> 
</compound> 

如果你想生產的cat所有 disting值類似的結果,這是一次簡短

<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="kCatByVal" match="cat" use="."/> 
<xsl:key name="kColorByVal" match="color" use="."/> 
<xsl:key name="kTestByCat" match="test" use="cetval/cat"/> 

<xsl:variable name="vDistinctColors" select= 
    "/*/*/set/color[generate-id()=generate-id(key('kColorByVal',.)[1])]"/> 

<xsl:template match="/"> 
    <xsl:apply-templates select= 
    "/*/*/cetval/cat 
     [generate-id() 
     = generate-id(key('kCatByVal',.)[1])]"/> 
</xsl:template> 

<xsl:template match="cat"> 
    <xsl:variable name="vcurCat" select="."/> 
    <compound> 
    <cat><xsl:apply-templates/></cat> 
    <xsl:for-each select="$vDistinctColors"> 
    <xsl:apply-templates select= 
     "(key('kCatByVal',$vcurCat)/../../set/color[.=current()])[1]"> 
     <xsl:with-param name="pCat" select="$vcurCat"/> 
     </xsl:apply-templates> 
    </xsl:for-each> 
    </compound> 
</xsl:template> 

<xsl:template match="color"> 
    <xsl:param name="pCat"/> 

    <xsl:copy-of select="."/> 
    <xsl:copy-of select="key('kTestByCat',$pCat)[set/color=current()]/title"/> 
</xsl:template> 
</xsl:stylesheet> 

當在同一個XML文檔應用(以上),現在的結果是:

<compound> 
    <cat>abc</cat> 
    <color>blue</color> 
    <title>k</title> 
    <title>r</title> 
    <color>yellow</color> 
    <title>j</title> 
    <title>w</title> 
</compound> 
<compound> 
    <cat>fcg</cat> 
    <color>blue</color> 
    <title>k</title> 
    <color>pink</color> 
    <title>p</title> 
    <color>yellow</color> 
    <title>j</title> 
</compound> 
<compound> 
    <cat>klm</cat> 
    <color>pink</color> 
    <title>p</title> 
    <color>yellow</color> 
    <title>j</title> 
</compound> 
<compound> 
    <cat>dji</cat> 
</compound> 
<compound> 
    <cat>kfjsdlk</cat> 
</compound> 
<compound> 
    <cat>deiu</cat> 
    <color>blue</color> 
    <title>r</title> 
</compound> 
<compound> 
    <cat>kfjdf</cat> 
    <color>blue</color> 
    <title>r</title> 
</compound>