2012-07-04 6 views
2

Мне нужно преобразовать XML IDOC xml в формат AdsML. Но абстрактный вопрос: как преобразовать xml1 в xml2?XSLT 1.0: преобразование IDOC в AdsML

xml1:

<E1BPBUSISM008_ITEM_OUT> 
    <ITEM_NUMBER>010</ITEM_NUMBER> 
</E1BPBUSISM008_ITEM_OUT> 
<E1BPBUSISM008_ITEM_OUT> 
    <ITEM_NUMBER>020</ITEM_NUMBER> 
</E1BPBUSISM008_ITEM_OUT> 

<E1BPBUSISM008_AD_SPEC_AD_OU> 
    <ITEM_NUMBER>010</ITEM_NUMBER> 
    <PLANNED_WIDTH>1.851</PLANNED_WIDTH> 
    <PLANNED_HEIGHT>0.000</PLANNED_HEIGHT> 
</E1BPBUSISM008_AD_SPEC_AD_OU> 
<E1BPBUSISM008_AD_SPEC_AD_OU> 
    <ITEM_NUMBER>020</ITEM_NUMBER> 
    <PLANNED_WIDTH>2.37</PLANNED_WIDTH> 
    <PLANNED_HEIGHT>0.000</PLANNED_HEIGHT> 
</E1BPBUSISM008_AD_SPEC_AD_OU> 

в xml2:

<Ad> 
    <ad-number>010<ad-number> 
    <width>1.851</width> 
    <height>0.000</height> 
</Ad> 
<Ad> 
    <ad-number>020<ad-number> 
    <width>2.37</width> 
    <height>0.000</height> 
</Ad> 

То, что я пытался здесь является метод Мюнх, но даже если это правильное решение для этого случая, не знаю, как закончить его , потому что она возвращает неправильный 'ширина' и 'heigth' (то же самое для всех элементов Ad):

<xsl:key name="adnumbers" match="IE1BPBUSISM008_ITEM_OUT" use="ITEM_NUMBER"/> 
.... 
<xsl:for-each select="E1BPBUSISM008_ITEM_OUT[generate-id(.)=generate-id(key('adnumbers',ITEM_NUMBER)[1])]"> 
<xsl:sort select="ITEM_NUMBER"/> 
<Ad> 
<ad-number> 
    <xsl:value-of select="ITEM_NUMBER/text()"/> 
</ad-number> 
<width> 
<xsl:value-of select="E1BPBUSISM008_AD_SPEC_AD_OU/PLANNED_WIDTH"/> 
</width> 
<height> 
<xsl:value-of select="E1BPBUSISM008_AD_SPEC_AD_OU/PLANNED_HEIGHT"/> 
</height> 

выходы:

<Ad> 
    <number>010</ad-number> 
    <width>1.851</width> 
    <heigth>0.000</heigth> 
</Ad> 
<Ad> 
    <number>020</ad-number> 
    <width>1.851</width> 
    <heigth>0.000</heigth> 
</Ad> 

ответ

3

Вам не понадобится фактическая группировка Muenchian - использование ключа будет достаточным для получения желаемого результата.

<xsl:key name="k_AD_SPEC_AD_OU" match="E1BPBUSISM008_AD_SPEC_AD_OU" use="ITEM_NUMBER" /> 

<!-- ... --> 

<xsl:for-each select="E1BPBUSISM008_ITEM_OUT"> 
    <xsl:sort select="ITEM_NUMBER" /> 
    <Ad> 
     <ad-number> 
      <xsl:value-of select="ITEM_NUMBER" /> 
     </ad-number> 
     <width> 
      <xsl:value-of select="key('k_AD_SPEC_AD_OU', ITEM_NUMBER)[1]/PLANNED_WIDTH" /> 
     </width> 
     <height> 
      <xsl:value-of select="key('k_AD_SPEC_AD_OU', ITEM_NUMBER)[1]/PLANNED_HEIGHT" /> 
     </height> 
    </Ad> 
</xsl:for-each> 

<!-- ... --> 

Однако правильное решение зависит от соотношения между вашим E1BPBUSISM008_ITEM_OUT и E1BPBUSISM008_AD_SPEC_AD_OU: Ваш пример показывает, что это просто 1 к 1 которые сделали бы ключ ненужным, но я подозреваю, что ваше действительное отношение может быть довольно 1 до 0 или 1 или даже от 1 до 0 и более.

Если вам необходимо создать выходные данные для отсутствующих элементов E1BPBUSISM008_AD_SPEC_AD_OU (отношение 1 к 0 или 1), то xslt потребуется некоторое изменение.


Для простого 1 до 1 отношения вашего XSLT может выглядеть следующим образом:

<!-- ... --> 

<xsl:for-each select="E1BPBUSISM008_ITEM_OUT"> 
    <xsl:sort select="ITEM_NUMBER" /> 
    <Ad> 
     <ad-number> 
      <xsl:value-of select="ITEM_NUMBER" /> 
     </ad-number> 

     <xsl:call-template name="AD_SPEC_AD_OU"> 
      <xsl:with-param name="pITEM_NUMBER" select="ITEM_NUMBER" /> 
     </xsl:call-template> 
    </Ad> 
</xsl:for-each> 

<xsl:template name="AD_SPEC_AD_OU"> 
    <xsl:param name="pITEM_NUMBER" /> 

    <width> 
     <xsl:value-of select="//E1BPBUSISM008_AD_SPEC_AD_OU[ITEM_NUMBER = $pITEM_NUMBER]/PLANNED_WIDTH" /> 
    </width> 
    <height> 
     <xsl:value-of select="//E1BPBUSISM008_AD_SPEC_AD_OU[ITEM_NUMBER = $pITEM_NUMBER]/PLANNED_HEIGHT" /> 
    </height> 
</xsl:template>