用sequentail数替换xml值

时间:2015-08-05 12:50:17

标签: xslt

您好我一直在尝试用连续数字替换某个标签中的值,我使用了位置功能,但它不起作用。 输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
   <Header>
      <User id="swarnai" />
      <Request-Id id="592149819" />
      <Type name="Request" />
      <Application-Source version="8.1.1.10" name="Siebel" />
      <Application-Destination version="1.2.2" name="EVA" />
      <Outgo-Timestamp time="11:40:59" date="2015-08-04" />
      <DealerCode>82536</DealerCode>
      <Market>00000</Market>
   </Header>
   <Content>
      <ClaimContext>
         <ClaimControl>
            <ClaimEntryFlag>3</ClaimEntryFlag>
            <ClaimSaveFlag>1</ClaimSaveFlag>
         </ClaimControl>
         <Claim>
            <DealerClaimNumber>1091871</DealerClaimNumber>
            <WHC>WDD</WHC>
            <FIN>2120026L020301</FIN>
            <RegistrationNumber>JH07E2786</RegistrationNumber>
            <FirstRegistrationDate>2012-11-29</FirstRegistrationDate>
            <Mileage>14317</Mileage>
            <MileageIndicator>0</MileageIndicator>
            <RepairDate>2013-12-03</RepairDate>
            <RegularlyMaintained>true</RegularlyMaintained>
            <NoFirstRegDateInd>false</NoFirstRegDateInd>
            <ClaimCurrencyId>EUR</ClaimCurrencyId>
            <Taxi>false</Taxi>
            <DamagePosition>
               <DamageSeqNumber>1</DamageSeqNumber>
               <WarrantyType>0</WarrantyType>
               <DamageCode>0121504</DamageCode>
               <OperationPosition>
                  <SeqNumber>1</SeqNumber>
                  <Opcode>02770501</Opcode>
                  <WorkingUnits>18</WorkingUnits>
                  <MainOperationCode>true</MainOperationCode>
                  <OperationText>OPERATIONS: FITTING FOR       COOLANT CONNECTION TO CYLINDER</OperationText>
                  <PriceGroup>01</PriceGroup>
               </OperationPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>1</DamageSeqNumber>
               <WarrantyType>0</WarrantyType>
               <DamageCode>0121504</DamageCode>
               <PartPosition>
                  <SeqNumber>1</SeqNumber>
                  <Quantity>10</Quantity>
                  <PartNumber>A6512001056</PartNumber>
                  <DamageCausingPart>true</DamageCausingPart>
                  <RetailPriceAmount>1499</RetailPriceAmount>
                  <Express>false</Express>
               </PartPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>1</DamageSeqNumber>
               <WarrantyType>0</WarrantyType>
               <DamageCode>0121504</DamageCode>
               <PartPosition>
                  <SeqNumber>1</SeqNumber>
                  <Quantity>20</Quantity>
                  <PartNumber>A0009890825  10</PartNumber>
                  <DamageCausingPart>false</DamageCausingPart>
                  <RetailPriceAmount>1319</RetailPriceAmount>
                  <Express>false</Express>
               </PartPosition>
            </DamagePosition>
         </Claim>
      </ClaimContext>
   </Content>
</Envelope>

在PartPosition / SeqNumber标签中的这个xml中,我想在SeqNumber标签中替换或生成数字序列。

我在xslt:

下面尝试过
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:key name="Damage_Group" match="/Envelope/Content/ClaimContext/Claim/DamagePosition" use="DamageCode" />
<xsl:template match="Claim">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:for-each select="DamagePosition[count(. | key('Damage_Group', DamageCode)[1]) = 1]">
 <xsl:sort select="DamageCode" />
<DamagePosition>
<DamageSeqNumber>
<xsl:value-of select="position()" />
</DamageSeqNumber>
<DamageCode>
<xsl:value-of select="DamageCode" />
</DamageCode>
<WarrantyType><xsl:value-of select="WarrantyType" /></WarrantyType>
<xsl:for-each select="key('Damage_Group', DamageCode)">
<xsl:copy-of select="current()/PartPosition"/>
<xsl:copy-of select="current()/OperationPosition"/>
<xsl:copy-of select="current()/SubletPosition"/>
</xsl:for-each>
</DamagePosition>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="DamagePosition">
</xsl:template>
</xsl:stylesheet>

但它没有给我如下所需的输出。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
   <Header>
      <User id="swarnai" />
      <Request-Id id="592149819" />
      <Type name="Request" />
      <Application-Source version="8.1.1.10" name="Siebel" />
      <Application-Destination version="1.2.2" name="EVA" />
      <Outgo-Timestamp time="12:15:47" date="2015-08-04" />
      <DealerCode>82536</DealerCode>
      <Market>00000</Market>
   </Header>
   <Content>
      <ClaimContext>
         <ClaimControl>
            <ClaimEntryFlag>3</ClaimEntryFlag>
            <ClaimSaveFlag>1</ClaimSaveFlag>
         </ClaimControl>
         <Claim>
            <DealerClaimNumber>1091871</DealerClaimNumber>
            <WHC>WDD</WHC>
            <FIN>2120026L020301</FIN>
            <RegistrationNumber>JH07E2786</RegistrationNumber>
            <FirstRegistrationDate>2012-11-29</FirstRegistrationDate>
            <Mileage>14317</Mileage>
            <MileageIndicator>0</MileageIndicator>
            <RepairDate>2013-12-03</RepairDate>
            <RegularlyMaintained>true</RegularlyMaintained>
            <NoFirstRegDateInd>false</NoFirstRegDateInd>
            <ClaimCurrencyId>EUR</ClaimCurrencyId>
            <Taxi>false</Taxi>
            <DamagePosition>
               <DamageSeqNumber>1</DamageSeqNumber>
               <DamageCode>0121504</DamageCode>
               <WarrantyType>0</WarrantyType>
               <OperationPosition>
                  <SeqNumber>1</SeqNumber>
                  <Opcode>02770501</Opcode>
                  <WorkingUnits>18</WorkingUnits>
                  <MainOperationCode>true</MainOperationCode>
                  <OperationText>OPERATIONS: FITTING FOR       COOLANT CONNECTION TO CYLINDER</OperationText>
                  <PriceGroup>01</PriceGroup>
               </OperationPosition>
               <PartPosition>
                  <SeqNumber>1</SeqNumber>
                  <Quantity>10</Quantity>
                  <PartNumber>A6512001056</PartNumber>
                  <DamageCausingPart>true</DamageCausingPart>
                  <RetailPriceAmount>1499</RetailPriceAmount>
                  <Express>false</Express>
               </PartPosition>
               <PartPosition>
                  <SeqNumber>2</SeqNumber>
                  <Quantity>20</Quantity>
                  <PartNumber>A0009890825  10</PartNumber>
                  <DamageCausingPart>false</DamageCausingPart>
                  <RetailPriceAmount>1319</RetailPriceAmount>
                  <Express>false</Express>
               </PartPosition>
            </DamagePosition>
         </Claim>
      </ClaimContext>
   </Content>
</Envelope>

非常感谢任何帮助。

由于

1 个答案:

答案 0 :(得分:0)

首先,不要这样做,而是复制元素而不对其进行进一步的更改(或其后代)

<xsl:copy-of select="current()/PartPosition"/>
<xsl:copy-of select="current()/OperationPosition"/>
<xsl:copy-of select="current()/SubletPosition"/>

您应该进行模板匹配,以便稍后编写模板以更改序列号

<xsl:apply-templates select="PartPosition"/>
<xsl:apply-templates select="OperationPosition"/>
<xsl:apply-templates select="SubletPosition"/>

现在,您可以做的是编写一个匹配各种Sequence数字的模板,并计算同一DamageCode的前一个兄弟姐妹。像这样的东西

<xsl:template match="PartPosition/SeqNumber">
  <SeqNumber>
    <xsl:variable name="DamageCode" select="../../DamageCode" />
    <xsl:value-of select="count(../../preceding-sibling::*[PartPosition][DamageCode = $DamageCode]) + 1" />
  </SeqNumber>
</xsl:template>

您也可以重复OperationPositionSubletPosition的模板,尽管这会非常重复。或者,使用一个通用模板来匹配所有三个:

<xsl:template match="SeqNumber">
  <SeqNumber>
    <xsl:variable name="DamageCode" select="../../DamageCode" />
    <xsl:variable name="Parent" select="name(..)" />
    <xsl:value-of select="count(../../preceding-sibling::*[*[name() = $Parent]][DamageCode = $DamageCode]) + 1" />
  </SeqNumber>
</xsl:template>

然而,这并不一定有效,因为它没有使用密钥,因此必须通过所有前面的兄弟姐妹检查以找到匹配。

另一个解决方案是在参数中传递当前DamagePosition的位置,然后在检查密钥时使用它。

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" encoding="utf-8" indent="yes"/>
   <xsl:key name="Damage_Group"
            match="/Envelope/Content/ClaimContext/Claim/DamagePosition"
            use="DamageCode"/>

   <xsl:template match="Claim">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
         <xsl:for-each select="DamagePosition[count(. | key('Damage_Group', DamageCode)[1]) = 1]">
            <xsl:sort select="DamageCode"/>
            <DamagePosition>
               <DamageSeqNumber>
                  <xsl:value-of select="position()"/>
               </DamageSeqNumber>
               <DamageCode>
                  <xsl:value-of select="DamageCode"/>
               </DamageCode>
               <WarrantyType>
                  <xsl:value-of select="WarrantyType"/>
               </WarrantyType>
               <xsl:for-each select="key('Damage_Group', DamageCode)">
                  <xsl:apply-templates select="PartPosition">
                      <xsl:with-param name="Position" select="position()" />
                  </xsl:apply-templates>
                  <xsl:apply-templates select="OperationPosition">
                      <xsl:with-param name="Position" select="position()" />
                  </xsl:apply-templates>
                  <xsl:apply-templates select="SubletPosition">
                      <xsl:with-param name="Position" select="position()" />
                  </xsl:apply-templates>
               </xsl:for-each>
            </DamagePosition>
         </xsl:for-each>
      </xsl:copy>
   </xsl:template>

    <xsl:template match="DamagePosition/*">
     <xsl:param name="Position" />
      <xsl:copy>
         <xsl:apply-templates select="@*|node()">
                <xsl:with-param name="Position" select="$Position" />
          </xsl:apply-templates>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="SeqNumber">
      <xsl:param name="Position" />
      <SeqNumber>
        <xsl:value-of select="count(key('Damage_Group', ../../DamageCode)[position() &lt;= $Position][*[name() = name(current()/..)]])" />
      </SeqNumber>
   </xsl:template>

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

   <xsl:template match="DamagePosition" />
</xsl:stylesheet>