根据某些条件在父元素下移动元素

Moving an element under a parent element based upon some conditions

提问人:Prashant Tripathi 提问时间:11/8/2023 最后编辑:Siebe JongebloedPrashant Tripathi 更新时间:11/14/2023 访问量:86

问:

我是 XSLT 的新手,因此需要有关此问题的一些帮助

如何在XSLT中应用条件,以便

  1. 当 CDSwaps 和 CMBX 同时存在时,复制 CDSwaps 下的 CMBX 元素并删除 CMBX

  2. 如果原始输入 xml 中没有 CDSwaps,只需将 CMBX 和 CMBX 分别重命名为 CDSwaps 和 CDS

我有以下输入XML

案例 1

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <SubmitImportJobRequest xmlns="/cp/bdtbeans">
         <User>abc</User>
         <Client>qwe</Client>
         <Password>00000</Password>
         <JobName>CMBX_TEST</JobName>
         <UserAssets Owner="abc" EffectiveStartDate="2023-04-03">
            <CDSwaps>
               <CDS ID="28881002_8" IDType="LOCALID" Name="Buy Protection on Apple Inc" BARRAID="28881002_8" StartDate="2023-12-22" ExpirationDate="2028-12-22" ContractSize="1" AccrualBasis="ACT/360" PriceCurrency="USD" UnderlierID="US037833EJ59" UnderlierIDType="ISIN" DealSpread="100"/>
            </CDSwaps>
            <CMBXs>
               <CMBX ID="32083535_8" IDType="LOCALID" Name="Sell Protection on CMBX.NA.AAA Indices Series 15 V1" BARRAID="32083535_8" ContractSize="1" RecoveryRate="40" PriceCurrency="USD" StartDate="2022-12-20" ExpirationDate="2028-03-09" UnderlierID="137BENAO4" UnderlierIDType="MIP" DealSpread="50"/>
            </CMBXs>
         </UserAssets>
      </SubmitImportJobRequest>
   </s:Body>
</s:Envelope>

所需输出

<Logical>
  <UserInstruments Effective_Start_Date="2023-04-03" Owner="paqa">
    <CDSwaps xmlns="/cp/bdtbeans">
      <CDS AccrualBasis="ACT/360" Priority="BARRA" BARRAID="28881002_8" ContractSize="1" CouponFrequency="3M" DealSpread="100" ExpirationDate="2028-12-22" ID="28881002_8" IDType="LOCALID" Name="Buy Protection on Apple Inc" PriceCurrency="USD" RecoveryRate="4.0E1" StartDate="2023-12-22" Und_ID="US037833EJ59" Und_IDType="ISIN"/>
      <CDS Priority="BARRA" BARRAID="32083535_8" ContractSize="1" DealSpread="50" ExpirationDate="2028-03-09" ID="32083535_8" IDType="LOCALID" IsCMBX="true" Name="Sell Protection on CMBX.NA.AAA Indices Series 15 V1" PriceCurrency="USD" RecoveryRate="40" StartDate="2022-12-20" Und_ID="137BENAO4" Und_IDType="MIP"/>
    </CDSwaps>
  </UserInstruments>
</Logical>

案例 2

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <SubmitImportJobRequest xmlns="/cp/bdtbeans">
         <User>abc</User>
         <Client>qwe</Client>
         <Password>00000</Password>
         <JobName>CMBX_TEST</JobName>
         <UserAssets Owner="abc" EffectiveStartDate="2023-04-03">
            <CMBXs>
               <CMBX ID="32083535_8" IDType="LOCALID" Name="Sell Protection on CMBX.NA.AAA Indices Series 15 V1" BARRAID="32083535_8" ContractSize="1" RecoveryRate="40" PriceCurrency="USD" StartDate="2022-12-20" ExpirationDate="2028-03-09" UnderlierID="137BENAO4" UnderlierIDType="MIP" DealSpread="50"/>
            </CMBXs>
         </UserAssets>
      </SubmitImportJobRequest>
   </s:Body>
</s:Envelope>

所需输出

<Logical>
   <UserInstruments Effective_Start_Date="2023-04-03" Owner="paqa">
      <CDSwaps xmlns="/cp/bdtbeans">
         <CDS Priority="BARRA" BARRAID="32083535_8" ContractSize="1" DealSpread="50" ExpirationDate="2028-03-09" ID="32083535_8" IDType="LOCALID" IsCMBX="true" Name="Sell Protection on CMBX.NA.AAA Indices Series 15 V1" PriceCurrency="USD" RecoveryRate="40" StartDate="2022-12-20" Und_ID="137BENAO4" Und_IDType="MIP"/>
      </CDSwaps>
   </UserInstruments>
</Logical>

用于此转换的 XSLT

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:bdt="/cp/bdtbeans">
      
      <xsl:template match="node() | @*" >
          <xsl:copy>
              <xsl:apply-templates select="node() | @*"/>
          </xsl:copy>
      </xsl:template>

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

      <xsl:template match="bdt:CMBX">
          <xsl:element name="CDS">
              <xsl:apply-templates select="node() | @*"/>
          </xsl:element>
      </xsl:template>

</xsl:stylesheet>

如何在XSLT中应用条件,以便仅当输入XML中存在CDSwaps和CMBX标记时才发生所有这些复制和重命名CMBX元素的语句?

XML XSLT XSD XSLT-1.0

评论

0赞 Prashant Tripathi 11/8/2023
仅当输入XML中同时存在CMBXx和CDSwaps时,我才需要输出。我也可以在输入XML中拥有许多其他不同的标签。

答:

0赞 Siebe Jongebloed 11/14/2023 #1

试试这个:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:bdt="/cp/bdtbeans">
  
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>
  
  <!-- The default copy template -->
  <xsl:template match="node() | @*" >
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>

  <!-- The root template that will apply to the bdt:UserAssets element-->
  <xsl:template match="/">
    <xsl:apply-templates select=".//bdt:UserAssets"/>
  </xsl:template>
    
  <xsl:template match="bdt:UserAssets">
    <xsl:element name="Logical">
      <xsl:element name="UserInstruments">
        <xsl:apply-templates select="@*" />
        <!-- Test if one of bdt:CDSwaps/bdt:CDS|bdt:CMBXs/bdt:CMBX is present and if so create CDSwaps-element and apply to those-->
        <xsl:if test="bdt:CDSwaps/bdt:CDS|bdt:CMBXs/bdt:CMBX">
            <xsl:element name="CDSwaps" namespace="/cp/bdtbeans">
              <xsl:apply-templates select="bdt:CDSwaps/bdt:CDS|bdt:CMBXs/bdt:CMBX"/>
            </xsl:element>
          </xsl:if>
      </xsl:element>
    </xsl:element>
  </xsl:template>
  
  <!-- Match on bdt:CDSwaps/bdt:CDS|bdt:CMBXs/bdt:CMBX and make element CDS-->
  <xsl:template match="bdt:CMBX|bdt:CDS">
    <xsl:element name="CDS" namespace="/cp/bdtbeans">
      <xsl:apply-templates select="node() | @*"/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="@EffectiveStartDate">
    <xsl:attribute name="Effective_Start_Date"><xsl:value-of select="."/></xsl:attribute>
  </xsl:template>
  
  <xsl:template match="@Owner">
    <xsl:attribute name="Owner">paqa</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>