XSLT 1.0: преобразование IDOC в AdsML

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

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>

Здесь я пробовал метод Muench, но даже если это правильное решение для этого случая, не знаю, как его завершить, потому что он возвращает неправильную «ширину» и «высоту» (одинаковые для всех элементов объявления):

<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>

person Alyaksandr Stzhalkouski    schedule 04.07.2012    source источник


Ответы (1)


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

<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 to 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>
person Filburt    schedule 04.07.2012