2011-05-01 52 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> 

注意:混合子女和兄弟姐妹遍历。隧道参数。