2011-05-01 89 views
1

我有一個輸入XML,其具有以下結構,增量節點值動態

<VEN> 
<CUS> 
    <MEM> 
    <MEM> 
    <MEM> 
</CUS> 
<CUS> 
    <MEM> 
    <MEM> 
    <MEM> 
</CUS> 

每個節點中發生的輸入XML多次。每個MEM 節點中都有一個@ CLM01屬性,根據MEM節點的每20次出現,必須分配一個值。從第一個VEN/CUS開始,如果有55個MEM節點,那麼前20個節點的@ CLM01值爲'1',對於相同的VEN/CUS組合,接下來的20個節點的值爲'2',其餘15個節點將有@ CLM01值'3'。

對於在相同VEN下的下一個CUS(假設該CUS具有30個MEM節點),前20個MEM節點將具有@ CLM01值'4',並且接下來10個MEM將具有值'5'的@ CLM01。這繼續.....我希望我清楚我想要達到什麼。

謝謝。可能嗎?使用XSLT 1.0

下面是示例輸入

<Data> 
<VEN vendorId= "v1"> 
    <CUS custId = "c1"> 
     <MEM memId="m1" CLM01=""/> 
     <MEM memId="m2" CLM01=""/> 
     <MEM memId="m3" CLM01=""/> 
     <MEM memId="m4" CLM01=""/> 
     <MEM memId="m5" CLM01=""/> 
    </CUS> 
    <CUS custId = "c2"> 
     <MEM memId="m11" CLM01=""/> 
     <MEM memId="m12" CLM01=""/> 
     <MEM memId="m13" CLM01=""/> 
     <MEM memId="m14" CLM01=""/> 
     <MEM memId="m15" CLM01=""/> 
     <MEM memId="m16" CLM01=""/> 
     <MEM memId="m17" CLM01=""/> 
     <MEM memId="m18" CLM01=""/> 
    </CUS> 
</VEN> 
<VEN vendorId= "v2"> 
    <CUS custId = "c1"> 
     <MEM memId="m4" CLM01=""/> 
     <MEM memId="m5" CLM01=""/> 
     <MEM memId="m6" CLM01=""/> 
     <MEM memId="m7" CLM01=""/> 
     <MEM memId="m8" CLM01=""/> 
    </CUS> 
    <CUS custId = "c1"> 
     <MEM memId="m33" CLM01=""/> 
     <MEM memId="m44" CLM01=""/> 
     <MEM memId="m55" CLM01=""/> 
     <MEM memId="m66" CLM01=""/> 
     <MEM memId="m77" CLM01=""/> 
     <MEM memId="m88" CLM01=""/> 
     <MEM memId="m99" CLM01=""/> 
     <MEM memId="m11" CLM01=""/> 
    </CUS> 
</VEN> 

所需的輸出(MEM節點的代替20個OCCURENCES我們去每3個OCCURENCES)

<Data> 
<VEN vendorId= "v1"> 
    <CUS custId = "c1"> 
     <MEM memId="m1" CLM01="1"/> 
     <MEM memId="m2" CLM01="1"/> 
     <MEM memId="m3" CLM01="1"/> 
     <MEM memId="m4" CLM01="2"/> 
     <MEM memId="m5" CLM01="2"/> 
    </CUS> 
    <CUS custId = "c2"> 
     <MEM memId="m11" CLM01="3"/> 
     <MEM memId="m12" CLM01="3"/> 
     <MEM memId="m13" CLM01="3"/> 
     <MEM memId="m14" CLM01="4"/> 
     <MEM memId="m15" CLM01="4"/> 
     <MEM memId="m16" CLM01="4"/> 
     <MEM memId="m17" CLM01="5"/> 
     <MEM memId="m18" CLM01="5"/> 
    </CUS> 
</VEN> 
<VEN vendorId= "v2"> 
    <CUS custId = "c1"> 
     <MEM memId="m4" CLM01="6"/> 
     <MEM memId="m5" CLM01="6"/> 
     <MEM memId="m6" CLM01="6"/> 
     <MEM memId="m7" CLM01="7"/> 
     <MEM memId="m8" CLM01="7"/> 
    </CUS> 
    <CUS custId = "c1"> 
     <MEM memId="m33" CLM01="8"/> 
     <MEM memId="m44" CLM01="8"/> 
     <MEM memId="m55" CLM01="8"/> 
     <MEM memId="m66" CLM01="9"/> 
     <MEM memId="m77" CLM01="9"/> 
     <MEM memId="m88" CLM01="9"/> 
     <MEM memId="m99" CLM01="10"/> 
     <MEM memId="m11" CLM01="10"/> 
    </CUS> 
</VEN> 

+0

爲什麼不提供具有實際結構的格式良好的輸入?你想要產生的輸出?讓人們更容易找出你想要達到的目標。 – Lumi 2011-05-01 21:18:04

+0

@邁克爾:是的,你是對的。我想這會有所幫助。謝謝。我使用xsl:number存儲在變量中,但是我不知道如何在MEM的每3個節點之後實現遞增值的條件。 – bluesnowxyz 2011-05-01 22:18:37

+0

好問題,+1。查看我的答案獲得完整的解決方案。 – 2011-05-02 02:31:17

回答

1

此轉換

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

<xsl:param name="pSize" select="3"/> 


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

<xsl:template match="/"> 
    <xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates/> 
    </xsl:variable> 

    <xsl:variable name="vPass2" select= 
    "ext:node-set($vrtfPass1)"/> 

    <xsl:apply-templates select="$vPass2/*" mode="pass2"/> 
</xsl:template> 

<xsl:template match= 
    "MEM[not(following-sibling::MEM)]"> 
    <xsl:call-template name="identity"/> 

    <xsl:variable name="vPos" select= 
    "count(preceding-sibling::MEM)+1"/> 

    <xsl:variable name="pTimes" 
     select="$pSize - ($vPos mod $pSize)"/> 

    <xsl:call-template name="genMems"> 
    <xsl:with-param name="pTimes" select="$pTimes"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="genMems"> 
    <xsl:param name="pTimes"/> 

    <xsl:if test="$pTimes >0"> 
    <MEM fake="yes"/> 

    <xsl:call-template name="genMems"> 
    <xsl:with-param name="pTimes" select="$pTimes -1"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

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

<xsl:template match="MEM/@CLM01" mode="pass2"> 
    <xsl:attribute name="CLM01"> 
    <xsl:variable name="vNum"> 
    <xsl:number count="MEM" level="any"/> 
    </xsl:variable> 

    <xsl:value-of select= 
     "ceiling($vNum div $pSize)"/> 
    </xsl:attribute> 
    </xsl:template> 

    <xsl:template match="MEM[@fake='yes']" mode="pass2"/> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<Data> 
    <VEN vendorId= "v1"> 
     <CUS custId = "c1"> 
      <MEM memId="m1" CLM01=""/> 
      <MEM memId="m2" CLM01=""/> 
      <MEM memId="m3" CLM01=""/> 
      <MEM memId="m4" CLM01=""/> 
      <MEM memId="m5" CLM01=""/> 
     </CUS> 
     <CUS custId = "c2"> 
      <MEM memId="m11" CLM01=""/> 
      <MEM memId="m12" CLM01=""/> 
      <MEM memId="m13" CLM01=""/> 
      <MEM memId="m14" CLM01=""/> 
      <MEM memId="m15" CLM01=""/> 
      <MEM memId="m16" CLM01=""/> 
      <MEM memId="m17" CLM01=""/> 
      <MEM memId="m18" CLM01=""/> 
     </CUS> 
    </VEN> 
    <VEN vendorId= "v2"> 
     <CUS custId = "c1"> 
      <MEM memId="m4" CLM01=""/> 
      <MEM memId="m5" CLM01=""/> 
      <MEM memId="m6" CLM01=""/> 
      <MEM memId="m7" CLM01=""/> 
      <MEM memId="m8" CLM01=""/> 
     </CUS> 
     <CUS custId = "c1"> 
      <MEM memId="m33" CLM01=""/> 
      <MEM memId="m44" CLM01=""/> 
      <MEM memId="m55" CLM01=""/> 
      <MEM memId="m66" CLM01=""/> 
      <MEM memId="m77" CLM01=""/> 
      <MEM memId="m88" CLM01=""/> 
      <MEM memId="m99" CLM01=""/> 
      <MEM memId="m11" CLM01=""/> 
     </CUS> 
    </VEN> 
</Data> 

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

<Data> 
    <VEN vendorId="v1"> 
     <CUS custId="c1"> 
     <MEM memId="m1" CLM01="1"/> 
     <MEM memId="m2" CLM01="1"/> 
     <MEM memId="m3" CLM01="1"/> 
     <MEM memId="m4" CLM01="2"/> 
     <MEM memId="m5" CLM01="2"/> 
     </CUS> 
     <CUS custId="c2"> 
     <MEM memId="m11" CLM01="3"/> 
     <MEM memId="m12" CLM01="3"/> 
     <MEM memId="m13" CLM01="3"/> 
     <MEM memId="m14" CLM01="4"/> 
     <MEM memId="m15" CLM01="4"/> 
     <MEM memId="m16" CLM01="4"/> 
     <MEM memId="m17" CLM01="5"/> 
     <MEM memId="m18" CLM01="5"/> 
     </CUS> 
    </VEN> 
    <VEN vendorId="v2"> 
     <CUS custId="c1"> 
     <MEM memId="m4" CLM01="6"/> 
     <MEM memId="m5" CLM01="6"/> 
     <MEM memId="m6" CLM01="6"/> 
     <MEM memId="m7" CLM01="7"/> 
     <MEM memId="m8" CLM01="7"/> 
     </CUS> 
     <CUS custId="c1"> 
     <MEM memId="m33" CLM01="8"/> 
     <MEM memId="m44" CLM01="8"/> 
     <MEM memId="m55" CLM01="8"/> 
     <MEM memId="m66" CLM01="9"/> 
     <MEM memId="m77" CLM01="9"/> 
     <MEM memId="m88" CLM01="9"/> 
     <MEM memId="m99" CLM01="10"/> 
     <MEM memId="m11" CLM01="10"/> 
     </CUS> 
    </VEN> 
</Data> 

說明

  1. 兩通變換。

  2. 第一遍增加了假MEM元件,使得結果中的每一CUS元件具有MEM兒童的數量是$pSize的倍數。

  3. 第二關:

  4. 使用並覆蓋identity rule

  5. 使用<xsl:number>得到MEM正確的元素編號與level="any"

+0

+1。我真的從你的每一個帖子開始教育。謝謝! – snoofkin 2011-05-01 23:17:27

+0

@ soulSurfer2010:不客氣。 – 2011-05-01 23:29:22

+1

但是,OP的示例暗指的組不能跨越''個元素,所以每個''中的第一個組將總是擁有最大數量的成員,當然提供了足夠的元素。我已經給出了一些想法,但似乎很難解決。 – Lumi 2011-05-01 23:29:35

1

只是爲了好玩,一個合格的轉換:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pSize" select="3"/> 
    <xsl:template match="node()|@*"> 
     <xsl:param name="pOffset" select="0"/> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"> 
       <xsl:with-param name="pOffset" select="$pOffset"/> 
       <xsl:with-param name="pPosition" select="position()"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="VEN|CUS"> 
     <xsl:param name="pOffset" select="0"/> 
     <xsl:variable name="vIsVEN" select="self::VEN"/> 
     <xsl:copy> 
      <xsl:apply-templates 
      select="@*|node()[position()=1 and $vIsVEN or not($vIsVEN)]"> 
       <xsl:with-param name="pOffset" select="$pOffset"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
     <xsl:apply-templates select="following-sibling::node()[1]"> 
      <xsl:with-param name="pOffset" 
      select="$pOffset + count(.//MEM[position() mod $pSize = 1])"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="MEM/@CLM01"> 
     <xsl:param name="pPosition" select="1"/> 
     <xsl:param name="pOffset" select="0"/> 
     <xsl:attribute name="{name()}"> 
      <xsl:value-of 
      select="$pOffset + ceiling(($pPosition - 1) div $pSize)"/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<Data> 
    <VEN vendorId="v1"> 
     <CUS custId="c1"> 
      <MEM memId="m1" CLM01="1"></MEM> 
      <MEM memId="m2" CLM01="1"></MEM> 
      <MEM memId="m3" CLM01="1"></MEM> 
      <MEM memId="m4" CLM01="2"></MEM> 
      <MEM memId="m5" CLM01="2"></MEM> 
     </CUS> 
     <CUS custId="c2"> 
      <MEM memId="m11" CLM01="3"></MEM> 
      <MEM memId="m12" CLM01="3"></MEM> 
      <MEM memId="m13" CLM01="3"></MEM> 
      <MEM memId="m14" CLM01="4"></MEM> 
      <MEM memId="m15" CLM01="4"></MEM> 
      <MEM memId="m16" CLM01="4"></MEM> 
      <MEM memId="m17" CLM01="5"></MEM> 
      <MEM memId="m18" CLM01="5"></MEM> 
     </CUS> 
    </VEN> 
    <VEN vendorId="v2"> 
     <CUS custId="c1"> 
      <MEM memId="m4" CLM01="6"></MEM> 
      <MEM memId="m5" CLM01="6"></MEM> 
      <MEM memId="m6" CLM01="6"></MEM> 
      <MEM memId="m7" CLM01="7"></MEM> 
      <MEM memId="m8" CLM01="7"></MEM> 
     </CUS> 
     <CUS custId="c1"> 
      <MEM memId="m33" CLM01="8"></MEM> 
      <MEM memId="m44" CLM01="8"></MEM> 
      <MEM memId="m55" CLM01="8"></MEM> 
      <MEM memId="m66" CLM01="9"></MEM> 
      <MEM memId="m77" CLM01="9"></MEM> 
      <MEM memId="m88" CLM01="9"></MEM> 
      <MEM memId="m99" CLM01="10"></MEM> 
      <MEM memId="m11" CLM01="10"></MEM> 
     </CUS> 
    </VEN> 
    <VEN vendorId="v2"> 
     <CUS custId="c1"> 
      <MEM memId="m4" CLM01="1"></MEM> 
      <MEM memId="m5" CLM01="1"></MEM> 
      <MEM memId="m6" CLM01="1"></MEM> 
      <MEM memId="m7" CLM01="2"></MEM> 
      <MEM memId="m8" CLM01="2"></MEM> 
     </CUS> 
     <CUS custId="c1"> 
      <MEM memId="m33" CLM01="3"></MEM> 
      <MEM memId="m44" CLM01="3"></MEM> 
      <MEM memId="m55" CLM01="3"></MEM> 
      <MEM memId="m66" CLM01="4"></MEM> 
      <MEM memId="m77" CLM01="4"></MEM> 
      <MEM memId="m88" CLM01="4"></MEM> 
      <MEM memId="m99" CLM01="5"></MEM> 
      <MEM memId="m11" CLM01="5"></MEM> 
     </CUS> 
    </VEN> 
</Data> 

注意:混合子女和兄弟姐妹遍歷。隧道參數。