2013-07-15 153 views
0

我是XSLT的新手,我正在努力從嵌套結構轉換爲平面元素序列。 我的輸入是這樣的:XSLT嵌套到扁平結構

<SyncBillOfMaterialsListEBM> 
<EBMHeader/> 
<DataArea> 
    <Sync/> 
    <SyncBillOfMaterialsList/> 
    <SyncBillOfMaterialsList> 
     <Identification> 
      <ID>B31819K</ID> 
      <ContextID schemeID="AddedBOMs"/>       
     </Identification> 
     <BillOfMaterialsComponentItem/> 
</SyncBillOfMaterialsList> 

<SyncBillOfMaterialsList> 
    <Identification/> 
    <BillOfMaterialsComponentItem> 
     <Identification> 
      <BusinessComponentID schemeID="B31819K"/> 
      <ID>B31618R</ID> 
      <ContextID schemeID="AddedBOMComponents"/>    
     </Identification> 
     <Quantity>5</Quantity> 
     <FromUnitNumber>500</FromUnitNumber> 
     <TypeCode>IT1</TypeCode>  
     <BillOfMaterialsSubstituteComponentItem/>  
    </BillOfMaterialsComponentItem> 
</SyncBillOfMaterialsList> 

<SyncBillOfMaterialsList> 
    <Identification/> 
    <BillOfMaterialsComponentItem> 
     <Identification> 
      <BusinessComponentID schemeID="B31819K"/> 
      <ID>B31619S</ID> 
      <ContextID schemeID="AddedBOMComponents"/>  
     </Identification> 
     <Quantity>2</Quantity> 
     <FromUnitNumber>600</FromUnitNumber>  
     <TypeCode>IT1</TypeCode>  
    </BillOfMaterialsComponentItem> 
</SyncBillOfMaterialsList> 

<SyncBillOfMaterialsList> 
    <Identification/> 
    <BillOfMaterialsComponentItem> 
     <Identification/> 
      <BillOfMaterialsSubstituteComponentItem> 
       <Identification> 
        <BusinessComponentID schemeID="B31819K"/> 
        <ID>B31618R</ID> 
        <ContextID schemeID="AddedSubstitutes"/>       
       </Identification> 
       <Quantity>5</Quantity> 
       <ItemReference> 
        <ItemIdentification> 
         <ID>B31619S</ID>    
        </ItemIdentification> 
        <SpecificationGroup/> 
       </ItemReference> 
       <ChangeTypeCode>IT1</ChangeTypeCode> 
      </BillOfMaterialsSubstituteComponentItem>  
    </BillOfMaterialsComponentItem> 
</SyncBillOfMaterialsList> 

<SyncBillOfMaterialsList> 
    <Identification/>  
    <BillOfMaterialsComponentItem> 
     <Identification/>  
     <BillOfMaterialsSubstituteComponentItem> 
     <Identification> 
      <BusinessComponentID schemeID="B31819K"/> 
      <ID>B31619S</ID> 
      <ContextID schemeID="AddedSubstitutes"/>     
     </Identification> 
     <Quantity>2</Quantity> 
     <ItemReference> 
      <ItemIdentification> 
       <ID>B31820L</ID> 
          </ItemIdentification> 
     </ItemReference> 
     <ChangeTypeCode>IT1</ChangeTypeCode>   
     </BillOfMaterialsSubstituteComponentItem>  
    </BillOfMaterialsComponentItem> 
</SyncBillOfMaterialsList> 

輸出應該像下面

 <InputParameters>   
     <REV_ITEM>      
       <REVISED_ITEM_NAME>B31819K</REVISED_ITEM_NAME> 
     </REV_ITEML> 
     <REV_COMP>  
       <COMPONENT_ITEM_NAME>B31618R</COMPONENT_ITEM_NAME>     
     </REV_COMP> 
     <SUB_COMP_TBL_ITEM>     
       <REVISED_ITEM_NAME>B31819K</REVISED_ITEM_NAME>      
       <COMPONENT_ITEM_NAME>B31618R</COMPONENT_ITEM_NAME>     
       <SUBSTITUTE_COMPONENT_NAME>B31619S</SUBSTITUTE_COMPONENT_NAME> 
       <SUBSTITUTE_ITEM_QUANTITY>5</SUBSTITUTE_ITEM_QUANTITY> 
     </SUB_COMP_TBL_ITEM> 
    </InputParameters> 

    <InputParameters>   
     <REV_ITEM>      
       <REVISED_ITEM_NAME>B31819K</REVISED_ITEM_NAME> 
     </REV_ITEML> 
     <REV_COMP>  
       <COMPONENT_ITEM_NAME>B31618S</COMPONENT_ITEM_NAME>     
     </REV_COMP> 
     <SUB_COMP_TBL_ITEM>     
       <REVISED_ITEM_NAME>B31819K</REVISED_ITEM_NAME>      
       <COMPONENT_ITEM_NAME>B31618S</COMPONENT_ITEM_NAME>     
       <SUBSTITUTE_COMPONENT_NAME>B31619L</SUBSTITUTE_COMPONENT_NAME> 
       <SUBSTITUTE_ITEM_QUANTITY>2</SUBSTITUTE_ITEM_QUANTITY> 
     </SUB_COMP_TBL_ITEM> 
    </InputParameters> 

元素,因爲我的XSLT是不工作的列表迭代只每次都有一個元素,我無法找到迭代所有元素並在相同結構中獲取正確值的方式。

<xsl:template match="/"> 
<xsl:for-each select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList"> 
<xsl:choose> 
    <xsl:when test="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/BusinessComponentID/@schemeID != '' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/ID!='' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/BillOfMaterialsSubstituteComponentItem/ItemReference/ItemIdentification/ID!='' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/Identification/ID=/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/[email protected] AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/[email protected]=/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/BillOfMaterialsSubstituteComponentItem/ItemReference/ItemIdentification/ID > 
    <REV_ITEM>      
       <REVISED_ITEM_NAME><xsl:value-of select="SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/Identification/ID"/></REVISED_ITEM_NAME> 
    </REV_ITEML> 
    <REV_COMP>  
       <COMPONENT_ITEM_NAME><xsl:value-of select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/ID" /></COMPONENT_ITEM_NAME>     
    </REV_COMP> 
    <SUB_COMP_TBL_ITEM>     
       <REVISED_ITEM_NAME><xsl:value-of select="SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/Identification/ID"/></REVISED_ITEM_NAME>      
       <COMPONENT_ITEM_NAME><xsl:value-of select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/ComponentItemProcessingInstruction/Identification/ID" /></COMPONENT_ITEM_NAME>     
       <SUBSTITUTE_COMPONENT_NAME><xsl:value-of select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/BillOfMaterialsSubstituteComponentItem/ItemReference/ItemIdentification/ID"/></SUBSTITUTE_COMPONENT_NAME> 
       <SUBSTITUTE_ITEM_QUANTITY><xsl:value-of select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/BillOfMaterialsSubstituteComponentItem/Quantity"/></SUBSTITUTE_ITEM_QUANTITY> 
    </SUB_COMP_TBL_ITEM> 


    </xsl:when test="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/BusinessComponentID/@schemeID != '' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/ID!='' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/BillOfMaterialsSubstituteComponentItem/ItemReference/ItemIdentification/ID='' AND /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/Identification/ID=/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/[email protected]"> 

    <REV_ITEM>      
       <REVISED_ITEM_NAME><xsl:value-of select="SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/Identification/ID"/></REVISED_ITEM_NAME> 
    </REV_ITEML> 
    <REV_COMP>  
       <COMPONENT_ITEM_NAME><xsl:value-of select="/SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/ID" /></COMPONENT_ITEM_NAME>     
    </REV_COMP> 
    <SUB_COMP_TBL_ITEM>     
       <REVISED_ITEM_NAME><!--empty--></REVISED_ITEM_NAME>      
       <COMPONENT_ITEM_NAME><!--empty--></COMPONENT_ITEM_NAME>     
       <SUBSTITUTE_COMPONENT_NAME><!--empty--></SUBSTITUTE_COMPONENT_NAME> 
       <SUBSTITUTE_ITEM_QUANTITY><!--empty--></SUBSTITUTE_ITEM_QUANTITY> 
    </SUB_COMP_TBL_ITEM> 
    </xsl:when> 

    <xsl:when OTHERPOSIBILITIES> 
    </xsl:when> 
<xsl:otherwise> 
    <!-- EMPTY --> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:for-each> 
</xsl:template> 

任何幫助都非常值得讚賞,創建和操縱變量以指向正確的值需要我很多努力。

回答

0
  1. 這不會產生格式良好的XML,因爲匹配根節點的模板會生成一個包含三個文檔元素的文檔。

  2. 您的xslt格式不正確。在元素關閉之後,您需要打開另一個元素。

  3. 如果您發現自己正在編寫for-each,然後嘗試測試相關節點的某些特徵,那麼您應該使用apply-templates來代替。

  4. 沒有您的REVISED_ITEM_NAME元素將被填充,因爲沒有SyncBillOfMaterialsList元素,其子元素爲SyncBillOfMaterialsListEBM

  5. 相對於上下文節點創建XPath表達式,而不是嘗試從基於position()的文檔根再次找到它。例如而不是: /SyncBillOfMaterialsListEBM/DataArea/SyncBillOfMaterialsList[position()]/BillOfMaterialsComponentItem/Identification/BusinessComponentID/@schemeID,只需使用BillOfMaterialsComponentItem/Identification/BusinessComponentID/@schemeID。這更易於閱讀,並且position()的使用可能會很脆弱,因爲它不涉及父節點內節點的順序位置,而是指它在當前節點列表中的位置。如果您有一個XPath表達式明確選擇其父代中第五個孩子的節點,則position()將爲1,而不是5.

  6. 不要嘗試基於評估的條件集合創建整個樹一旦。它看起來像您的輸出中的每個InputParameters元素具有相同的形狀,但具有不同的值。因此,在您的SyncBillOfMaterialsList模板中,指定InputParameters樹的形狀一次,並有條件地填充其子元素。這將更易於維護和閱讀。