инкрементно увеличивать значение узла - PullRequest
1 голос
/ 02 мая 2011

У меня есть входной XML, который имеет следующую структуру:

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

каждый узел встречается несколько раз во входном XML.В каждом узле MEM есть атрибут @ CLM01, которому должно быть присвоено значение в зависимости от каждых 20 вхождений узлов MEM.Начиная с первого VEN / CUS, если имеется 55 узлов MEM, то первые 20 узлов будут иметь значение @ CLM01, равное «1», и для той же комбинации VEN / CUS следующие 20 узлов будут иметь значение «2», а остальные 15 узлов будут иметьимеют значение @ CLM01 '3'.

И для следующего CUS (при условии, что этот CUS имеет 30 узлов MEM) под тем же VEN первые двадцать узлов MEM будут иметь значение @ CLM01 '4' и следующие десять MEMбудет иметь @ CLM01 со значением '5'.Это продолжается ..... Я надеюсь, что я ясно, что я пытаюсь достичь.

Спасибо.Является ли это возможным?используя 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>

Желаемый вывод (вместо 20 вхождений узлов MEM мы используем каждые 3 вхождения)

<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>

Ответы [ 2 ]

1 голос
/ 03 мая 2011

Ради интереса, однопроходное преобразование:

<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>

Примечание : обход смешивания детей и братьев и сестер.Параметры туннелирования.

1 голос
/ 02 мая 2011

Это преобразование :

<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. Второйpass:

  4. Использование и переопределение правила идентификации .

  5. Использование <xsl:number> для получения правильной нумерации элементов MEM с level="any".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...