使用xslt的动态xml节点

时间:2014-02-10 13:06:39

标签: xml xslt

我在SAP中使用转换来生成XML文件。我已经通过仅引用显式节点实现了这一点。现在,要求是通过动态添加新节点来增强现有XML结果,这些新节点基于可以在数量上变化的多个标签。 这是XML源:

<!-- edited with XMLSpy v2011 rel. 3 sp1 (http://www.altova.com)-->
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
    <asx:values>
        <MSAPO01>
            <LOGICALID>SAP-AMG</LOGICALID>
            <COMPONENT>Whatever</COMPONENT>
            <CONFIRMATION>Always</CONFIRMATION>
            <CREATIONDATE/>
            <BOID/>
            <SYNC_CONFIRM>Never</SYNC_CONFIRM>
            <SYNC_ACTION>Change</SYNC_ACTION>
            <DATAAREA>
                <item>
                    <ACTION>Change</ACTION>
                    <STATUS_HEAD>Z00</STATUS_HEAD>
                    <CREATIONDATE/>
                    <VBELN>0050023362</VBELN>
                    <POSNR>000001</POSNR>
                    <SHIPTO>C001991</SHIPTO>
                    <QUALITY>C</QUALITY>
                    <MTSMTO>MTO</MTSMTO>
                    <INTEXP>IN</INTEXP>
                    <NTGEW>22.520 </NTGEW>
                    <GEWEI>TO</GEWEI>
                    <DELIVERYMODE>Librex</DELIVERYMODE>
                    <PROPERTIES>
                        <ZPEL_PROPERTY_S>
                            <ID>ACTION</ID>
                            <DESCRIPTION>Action code</DESCRIPTION>
                            <DATAVALUE>007</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>002</ANY>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>AUGRU</ID>
                            <DESCRIPTION>Order reason (reason for the business transaction)</DESCRIPTION>
                            <DATAVALUE>01</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY/>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>ZTERM</ID>
                            <DESCRIPTION>Terms of payment key</DESCRIPTION>
                            <DATAVALUE>0401</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY/>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>QUALF</ID>
                            <DESCRIPTION>IDOC qualifier reference document</DESCRIPTION>
                            <DATAVALUE>001</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>Z022</ANY>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>QUALF</ID>
                            <DESCRIPTION>IDOC qualifier reference document</DESCRIPTION>
                            <DATAVALUE>002</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>Z023</ANY>
                        </ZPEL_PROPERTY_S>
                    </PROPERTIES>
                </item>
            </DATAAREA>
        </MSAPO01>
    </asx:values>
</asx:abap>

动态确定“属性”节点(数量和内容)。我原来的XSLT是:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.siemens.com/ad/mes/b2mt-1.0" xmlns:amg="Pelican@AMG" xmlns:bml="http://www.wbf.org/xml/b2mml-v02" xmlns:oag="http://www.openapplications.org/oagis"
xmlns:sit="http://www.siemens.com/ad/mes/b2mml-v02-SITExt-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.siemens.com/ad/mes/b2mt-1.0 C:\DATA_EXCHANGE\B2MT\B2MT_Schemas\AMG_ProductionSchedule.xsd">
  <xsl:template match="MSAPO01">
    <SyncProductionSchedule>
      <oag:ApplicationArea>
        <oag:Sender>
          <oag:LogicalId>
            <xsl:value-of select="LOGICALID"/>
          </oag:LogicalId>
          <oag:Component>
            <xsl:value-of select="COMPONENT"/>
          </oag:Component>
          <oag:Confirmation>
            <xsl:value-of select="CONFIRMATION"/>
          </oag:Confirmation>
        </oag:Sender>
        <oag:CreationDateTime>
          <xsl:value-of select="CREATIONDATE"/>
        </oag:CreationDateTime>
        <oag:BODId>
          <xsl:text>0000000000017092</xsl:text>
        </oag:BODId>
      </oag:ApplicationArea>
      <DataArea>
        <xsl:comment> WorkOrder  </xsl:comment>
        <oag:Sync>
          <xsl:attribute name="confirm">
            <xsl:value-of select="SYNC_CONFIRM"/>
          </xsl:attribute>
          <oag:SyncCriteria>
            <oag:SyncExpression>
              <xsl:attribute name="action">
                <xsl:value-of select="SYNC_ACTION"/>
              </xsl:attribute>
            </oag:SyncExpression>
          </oag:SyncCriteria>
        </oag:Sync>
        <xsl:apply-templates select="DATAAREA"/>
      </DataArea>
    </SyncProductionSchedule>
  </xsl:template>
  <xsl:template match="DATAAREA">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="DATAAREA/item">
    <bml:ProductionSchedule>
      <bml:ID>
        <xsl:text>Default</xsl:text>
      </bml:ID>
      <bml:ProductionRequest>
        <bml:ID>
          <xsl:value-of select="concat(VBELN,'/',POSNR)"/>
        </bml:ID>
        <bml:Any>
          <sit:ProductionRequestExtension>
            <sit:Quantity>
              <bml:QuantityString>
                <xsl:value-of select="NTGEW"/>
              </bml:QuantityString>
              <bml:DataType>
                <xsl:text>float</xsl:text>
              </bml:DataType>
              <bml:UnitOfMeasure>
                <xsl:value-of select="GEWEI"/>
              </bml:UnitOfMeasure>
            </sit:Quantity>
            <sit:ProducedQuantity>
              <xsl:value-of select="PROD_QTY"/>
            </sit:ProducedQuantity>
          </sit:ProductionRequestExtension>
          <amg:ProductionRequestExtension>
            <amg:SAPOrder>
              <amg:SAPOrderID>
                <xsl:value-of select="VBELN"/>
              </amg:SAPOrderID>
              <amg:SAPOrderItem>
                <xsl:value-of select="POSNR"/>
              </amg:SAPOrderItem>
              <amg:SAPStatusHead>
                <xsl:value-of select="STATUS_HEAD"/>
              </amg:SAPStatusHead>              
              <amg:SoldTo>
                <xsl:value-of select="SOLDTO"/>
              </amg:SoldTo>
              <amg:SoldToName>
                <xsl:value-of select="NAME_SOLDTO"/>
              </amg:SoldToName>
              <amg:ShipTo>
                <xsl:value-of select="SHIPTO"/>
              </amg:ShipTo>             
              <amg:Quality>
                <xsl:value-of select="QUALITY"/>
              </amg:Quality>
              <amg:DistributionChannel>
                <xsl:value-of select="INTEXP"/>
              </amg:DistributionChannel>
              <amg:DeliveryMode>
                <xsl:value-of select="DELIVERYMODE"/>
              </amg:DeliveryMode>
            </amg:SAPOrder>
          </amg:ProductionRequestExtension>
        </bml:Any>
      </bml:ProductionRequest>
    </bml:ProductionSchedule>
  </xsl:template>
</xsl:transform>

请帮我处理XSLT文件中的动态部分,以获得以下输出,无论属性的数量如何。 XML输出应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- edited with XMLSpy v2011 rel. 3 sp1 (http://www.altova.com) -->
<SyncProductionSchedule xmlns="http://www.siemens.com/ad/mes/b2mt-1.0" xmlns:amg="Pelican@ArcelorMittalGalati" xmlns:bml="http://www.wbf.org/xml/b2mml-v02" xmlns:oag="http://www.openapplications.org/oagis" xmlns:sit="http://www.siemens.com/ad/mes/b2mml-v02-SITExt-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <oag:ApplicationArea>
        <oag:Sender>
            <oag:LogicalId>SAP-AMG</oag:LogicalId>
            <oag:Component>Whatever</oag:Component>
            <oag:Confirmation>Always</oag:Confirmation>
        </oag:Sender>
        <oag:CreationDateTime>2014-02-10T12:52:32</oag:CreationDateTime>
        <oag:BODId>0000000000017092</oag:BODId>
    </oag:ApplicationArea>
    <DataArea>
        <!-- WorkOrder  -->
        <oag:Sync confirm="Never">
            <oag:SyncCriteria>
                <oag:SyncExpression action="Change"/>
            </oag:SyncCriteria>
        </oag:Sync>
        <bml:ProductionSchedule>
            <bml:ID>Default</bml:ID>
            <bml:ProductionRequest>
                <bml:ID>0050023362/000001</bml:ID>
                <bml:Any>
                    <sit:ProductionRequestExtension>
                        <sit:Quantity>
                            <bml:QuantityString>22.520 </bml:QuantityString>
                            <bml:DataType>float</bml:DataType>
                            <bml:UnitOfMeasure>TO</bml:UnitOfMeasure>
                        </sit:Quantity>
                        <sit:ProducedQuantity>0.000 </sit:ProducedQuantity>
                    </sit:ProductionRequestExtension>
                    <amg:ProductionRequestExtension>
                        <amg:SAPOrder>
                            <amg:SAPOrderID>0050023362</amg:SAPOrderID>
                            <amg:SAPOrderItem>000001</amg:SAPOrderItem>
                            <amg:SAPStatusHead>Z00</amg:SAPStatusHead>
                            <amg:SoldTo>C001991</amg:SoldTo>
                            <amg:Quality>C</amg:Quality>
                            <amg:DistributionChannel>IN</amg:DistributionChannel>
                            <amg:DeliveryMode>Librex</amg:DeliveryMode>
                            <!-- New Node - OrderProperty -> Begin  -->
                            <amg:SAPOrderProperties>
                                <amg:OrderProperty>
                                    <amg:ID>ACTION</amg:ID>
                                    <amg:Description>Action code</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>007</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>002</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>AUGRU</amg:ID>
                                    <amg:Description>Order reason (reason for the business transaction)</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>01</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any/>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>ZTERM</amg:ID>
                                    <amg:Description>Terms of payment key</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>0401</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any/>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>QUALF</amg:ID>
                                    <amg:Description>IDOC qualifier reference document</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>001</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>Z022</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>QUALF</amg:ID>
                                    <amg:Description>IDOC qualifier reference document</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>001</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>Z023</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                            </amg:SAPOrderProperties>
                            <!-- New Node - OrderProperty -> End -->
                        </amg:SAPOrder>
                    </amg:ProductionRequestExtension>
                </bml:Any>
            </bml:ProductionRequest>
        </bml:ProductionSchedule>
    </DataArea>
</SyncProductionSchedule>

1 个答案:

答案 0 :(得分:0)

这似乎是您现有样式表的直接扩展,您只需添加PROPERTIESZPEL_PROPERTY_S的模板

<xsl:template match="PROPERTIES">
  <amg:SAPOrderProperties>
    <xsl:apply-templates select="ZPEL_PROPERTY_S"/>
  </amg:SAPOrderProperties>
</xsl:template>

<xsl:template match="ZPEL_PROPERTY_S">
  <amg:OrderProperty>
    <amg:ID><xsl:value-of select="ID" /></amg:ID>
    <!-- etc. -->
  </amg:OrderProperty>
</xsl:template>

并在适当的地方应用这些模板

          <amg:DeliveryMode>
            <xsl:value-of select="DELIVERYMODE"/>
          </amg:DeliveryMode>
          <xsl:apply-templates select="PROPERTIES" />
        </amg:SAPOrder>