2017-06-15 78 views
0

我需要通過比較兩個不同的XPath創建一個XSLT和兩個孩子小號獲得價值和轉換XML。XSLT問題比較兩個XPath和轉換XML

規則如下:

1.)I need to compare the location-number inside buildings/building/building-header/location-number with buildings/policy/coverages/coverage/location-rule/insured-objects/insured-object/insured-object-nr and for the locations not matching i need to create element Policy/PolicyConditions/Name as No coverage and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number ie.,LU4-B1 in my below example. 

2.)for each buildings/policy/coverages/coverage check for limit/limit-type/@code is Bla and for each location-rule/insured-objects/insured-object/insured-object-nr check for location-number inside buildings/building/building-header/location-number and get the 
buildings/building/building-header/building-number create Policy/PolicyConditions/Name as EQ Blanket and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number LU1-B1,LU1-B1,LU2-B2 

3.)for each buildings/policy/coverages/coverage check for limit/limit-type/@code is Sub and for each location-rule/insured-objects/insured-object/insured-object-nr check for location-number inside buildings/building/building-header/location-number and get the 
buildings/building/building-header/building-number create Policy/PolicyConditions/Name as EQ Sublimit and map the Policy/PolicyConditions/PolicyConditionCriteria/Value as the building-number LU2-B1,LU2-B2,LU3-B1,LU3-B2 

Rule 2 and 3 are more or less the same only check that is different is with the limit/limit-type/@code. 

亞姆能夠acheive規則2和規則3但不能夠寫入的邏輯來acheive規則1爲不匹配的XPath。

我僅可以使用XSLT版本1.0

輸入:

<buildings> 
<building> 
      <building-header> 
       <location-number>LU1</location-number> 
       <building-number>LU1-B1</building-number> 
      </building-header> 
</building> 
<building> 
      <building-header> 
       <location-number>LU2</location-number> 
       <building-number>LU2-B1</building-number> 
      </building-header> 
</building> 
<building> 
      <building-header> 
       <location-number>LU2</location-number> 
       <building-number>LU2-B2</building-number> 
      </building-header> 
</building> 
<building> 
      <building-header> 
       <location-number>LU3</location-number> 
       <building-number>LU3-B1</building-number> 
      </building-header> 
</building> 
<building> 
      <building-header> 
       <location-number>LU3</location-number> 
       <building-number>LU3-B2</building-number> 
      </building-header> 
</building> 
<building> 
      <building-header> 
       <location-number>LU4</location-number> 
       <building-number>LU4-B1</building-number> 
      </building-header> 
</building>  

<policy-details> 
<coverages> 
<coverage> 
<limit> 
     <limit-type code="Bla"/> 
</limit> 
<location-rule> 
         <insured-objects> 
          <insured-object> 
           <insured-object-nr>LU1</insured-object-nr> 
          </insured-object> 
          <insured-object> 
           <insured-object-nr>LU2</insured-object-nr> 
          </insured-object> 
         </insured-objects> 
</location-rule> 
</coverage> 
<coverage> 
<limit> 
     <limit-type code="Sub"/> 
</limit> 
<location-rule> 
         <insured-objects> 
          <insured-object> 
           <insured-object-nr>LU2</insured-object-nr> 
          </insured-object> 
          <insured-object> 
           <insured-object-nr>LU3</insured-object-nr> 
          </insured-object> 
         </insured-objects> 
</location-rule> 
</coverage> 
</coverages> 
</policy> 
</buildings> 

示例XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 
<xsl:template match="/"> 
<policy> 
<xsl:for-each select="//coverage"> 
<xsl:if test="limit/limit-type/@code='Bla'"> 
<PolicyConditions> 
<Name>EQ Blanket</Name> 
<xsl:for-each select="location-rule/insured-objects/insured-object"> 
<xsl:variable name="var_Ins_Obj"> 
    <xsl:value-of select="insured-object-nr"/> 
</xsl:variable> 
<xsl:for-each select="//building"> 
                <xsl:variable name="var_loc_Num"> 
                 <xsl:value-of select="building-header/location-number"/> 
                </xsl:variable> 
                <xsl:if test="$var_loc_Num=$var_Ins_Obj"> 
                 <xsl:variable name="locBuild"> 
                  <xsl:value-of select="building-header/building-number"/> 
                 </xsl:variable> 
                 <PolicyConditionCriteria> 
                  <Field>LOCNAME</Field> 
                  <Value> 
                   <xsl:value-of select="$locBuild"/> 
                  </Value> 
                 </PolicyConditionCriteria> 
                </xsl:if> 
               </xsl:for-each> 
</xsl:for-each> 
</PolicyConditions> 
</xsl:if> 
<xsl:if test="limit/limit-type/@code='Sub'"> 
<PolicyConditions> 
<Name>EQ Sublimit</Name> 
<xsl:for-each select="location-rule/insured-objects/insured-object"> 
<xsl:variable name="var_Ins_Obj"> 
    <xsl:value-of select="insured-object-nr"/> 
</xsl:variable> 
<xsl:for-each select="//building"> 
                <xsl:variable name="var_loc_Num"> 
                 <xsl:value-of select="building-header/location-number"/> 
                </xsl:variable> 
                <xsl:if test="$var_loc_Num=$var_Ins_Obj"> 
                 <xsl:variable name="locBuild"> 
                  <xsl:value-of select="building-header/building-number"/> 
                 </xsl:variable> 
                 <PolicyConditionCriteria> 
                  <Field>LOCNAME</Field> 
                  <Value> 
                   <xsl:value-of select="$locBuild"/> 
                  </Value> 
                 </PolicyConditionCriteria> 
                </xsl:if> 
               </xsl:for-each> 
</xsl:for-each> 
</PolicyConditions> 
</xsl:if> 
</xsl:for-each> 
</policy> 
</xsl:template> 
</xsl:stylesheet> 

實際輸出:

<policy> 
    <PolicyConditions> 
     <Name>EQ Blanket</Name> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU1-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B2</Value> 
     </PolicyConditionCriteria> 
    </PolicyConditions> 
    <PolicyConditions> 
     <Name>EQ Sublimit</Name> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B2</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU3-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU3-B2</Value> 
     </PolicyConditionCriteria> 
    </PolicyConditions> 

預期輸出:

<Policy> 
    <PolicyConditions> 
     <Name>No Coverage</Name> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU4-B1</Value> 
     </PolicyConditionCriteria> 
    </PolicyConditions> 
    <PolicyConditions> 
     <Name>EQ Blanket</Name> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU1-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B2</Value> 
     </PolicyConditionCriteria> 
    </PolicyConditions> 
    <PolicyConditions> 
     <Name>EQ Sublimit</Name> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU2-B2</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU3-B1</Value> 
     </PolicyConditionCriteria> 
     <PolicyConditionCriteria> 
     <Field>LOCNAME</Field> 
     <Value>LU3-B2</Value> 
     </PolicyConditionCriteria> 
    </PolicyConditions> 
</Policy> 

回答

0

這裏是一個解決方案:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:variable name="noCoverage"> 
     <xsl:for-each select="//building/building-header/location-number"> 
      <xsl:variable name="locationNumber" select="text()"/> 
      <xsl:if test="boolean(//coverage/location-rule/insured-objects/insured-object/insured-object-nr[text()=$locationNumber]) = false"> 
       <xsl:value-of select="'true'"/> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 

    <xsl:template match="/"> 
     <policy> 
      <xsl:if test="contains($noCoverage, 'true')"> 
       <PolicyConditions> 
        <Name>No Coverage</Name> 
        <xsl:for-each select="//building/building-header/location-number"> 
         <xsl:variable name="locationNr" select="text()"/> 
         <xsl:if test="boolean(//coverage/location-rule/insured-objects/insured-object/insured-object-nr[text()=$locationNr]) = false"> 
          <PolicyConditionCriteria> 
           <Field>LOCNAME</Field> 
           <Value> 
            <xsl:value-of select="../building-number"/> 
           </Value> 
          </PolicyConditionCriteria> 
         </xsl:if> 
        </xsl:for-each>  
       </PolicyConditions> 
      </xsl:if> 

      <xsl:for-each select="//coverage"> 
       <xsl:if test="limit/limit-type/@code='Bla'"> 
        <PolicyConditions> 
         <Name>EQ Blanket</Name> 
         <xsl:for-each select="location-rule/insured-objects/insured-object"> 
          <xsl:variable name="var_Ins_Obj"> 
           <xsl:value-of select="insured-object-nr"/> 
          </xsl:variable> 
          <xsl:for-each select="//building"> 
           <xsl:variable name="var_loc_Num"> 
            <xsl:value-of select="building-header/location-number"/> 
           </xsl:variable> 
           <xsl:if test="$var_loc_Num=$var_Ins_Obj"> 
            <xsl:variable name="locBuild"> 
             <xsl:value-of select="building-header/building-number"/> 
            </xsl:variable> 
            <PolicyConditionCriteria> 
             <Field>LOCNAME</Field> 
             <Value> 
              <xsl:value-of select="$locBuild"/> 
             </Value> 
            </PolicyConditionCriteria> 
           </xsl:if> 
          </xsl:for-each> 
         </xsl:for-each> 
        </PolicyConditions> 
       </xsl:if> 
       <xsl:if test="limit/limit-type/@code='Sub'"> 
        <PolicyConditions> 
         <Name>EQ Sublimit</Name> 
         <xsl:for-each select="location-rule/insured-objects/insured-object"> 
          <xsl:variable name="var_Ins_Obj"> 
           <xsl:value-of select="insured-object-nr"/> 
          </xsl:variable> 
          <xsl:for-each select="//building"> 
           <xsl:variable name="var_loc_Num"> 
            <xsl:value-of select="building-header/location-number"/> 
           </xsl:variable> 
           <xsl:if test="$var_loc_Num=$var_Ins_Obj"> 
            <xsl:variable name="locBuild"> 
             <xsl:value-of select="building-header/building-number"/> 
            </xsl:variable> 
            <PolicyConditionCriteria> 
             <Field>LOCNAME</Field> 
             <Value> 
              <xsl:value-of select="$locBuild"/> 
             </Value> 
            </PolicyConditionCriteria> 
           </xsl:if> 
          </xsl:for-each> 
         </xsl:for-each> 
        </PolicyConditions> 
       </xsl:if> 
      </xsl:for-each> 

     </policy> 
    </xsl:template> 
</xsl:stylesheet> 

基本上,我添加了一個變量,其中我檢查是否存在與沒有相應的保險對象-NR的位置號碼。如果有的話,我在變量的值中添加字符串'true'。

然後,在模板中我檢查變量名,並再次檢查當前的位置,數量是否不具有相應的參保對象-NR。

+0

感謝您的解決方案就幫助了很多。 – Ravi

+0

親愛的瑪麗亞,我們發現,在這種方法的限制,該方法假設元素參保對象-NR和和位置號碼都位於一個獨特的XPATH。如果xml更改並且將來會有不同xpath的新元素具有相同名稱,那麼我們不會注意到這一點,並且會遇到錯誤。是否有其他選擇? – Ravi

+0

是的,您可以指定xpath,就像您在xslt的其他部分所做的一樣。我會編輯我的答案。 –