2012-07-04 2 views
1

Есть ли способ преобразовать xml1 в xml2 с помощью XSLT 1.0?Слияние элементов, которые не имеют прямых ссылок

xml1:

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

<E1BPBUSISM008_ITEM_AD_OUT> 
    <ITEM_NUMBER>010</ITEM_NUMBER> 
    <AD_SPEC_NO>000001</AD_SPEC_NO> 
</E1BPBUSISM008_ITEM_AD_OUT> 
<E1BPBUSISM008_ITEM_AD_OUT> 
    <ITEM_NUMBER>020</ITEM_NUMBER> 
    <AD_SPEC_NO>000002</AD_SPEC_NO> 
</E1BPBUSISM008_ITEM_AD_OUT> 

<E1BPBUSISM008_AD_SPEC_AD_OU> 
    <AD_SPEC_NO>000001</AD_SPEC_NO> 
    <KEYWORD>key1</KEYWORD> 
</E1BPBUSISM008_AD_SPEC_AD_OU> 
<E1BPBUSISM008_AD_SPEC_AD_OU> 
    <AD_SPEC_NO>000002</AD_SPEC_NO> 
    <KEYWORD>key2</KEYWORD> 
</E1BPBUSISM008_AD_SPEC_AD_OU> 

в xml2:

<Ad> 
    <ad-number>010</ad-number> 
    <keyword>key1</keyword> 
</Ad> 
<Ad> 
    <ad-number>020</ad-number> 
    <keyword>key2</keyword> 
</Ad> 

Если нет никакого способа сделать прямое преобразование, это помогло бы объединить xml1 во что-то вроде:

<E1BPBUSISM008_ITEM_OUT> 
    <ITEM_NUMBER>010</ITEM_NUMBER> 
    <KEYWORD>key1</KEYWORD> 
</E1BPBUSISM008_ITEM_OUT> 
<E1BPBUSISM008_ITEM_OUT> 
    <ITEM_NUMBER>020</ITEM_NUMBER> 
    <KEYWORD>key2</KEYWORD> 
</E1BPBUSISM008_ITEM_OUT> 
+0

Александр Stzhalkovski: Ответ, который вы в настоящее время принимаете, не так хорош и точен, как лучший ответ, поданный - на @TimC. –

ответ

2

Вы можете использовать два ключа для поиска данных. Во-первых, чтобы посмотреть E1BPBUSISM008_ITEM_AD_OUT элементы по ITEM_NUMBER

<xsl:key name="ad1" match="E1BPBUSISM008_ITEM_AD_OUT" use="ITEM_NUMBER" /> 

Тогда один, чтобы посмотреть E1BPBUSISM008_AD_SPEC_AD_OU элементы по AD_SPEC_NO

<xsl:key name="ad2" match="E1BPBUSISM008_AD_SPEC_AD_OU" use="AD_SPEC_NO" /> 

Тогда для данного E1BPBUSISM008_ITEM_OUT элемента, вы получит ключевое слово вот так

<xsl:value-of select="key('ad2', key('ad1', ITEM_NUMBER)/AD_SPEC_NO)/KEYWORD" /> 

Таким образом, учитывая следующие XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="ad1" match="E1BPBUSISM008_ITEM_AD_OUT" use="ITEM_NUMBER" /> 
    <xsl:key name="ad2" match="E1BPBUSISM008_AD_SPEC_AD_OU" use="AD_SPEC_NO" /> 

    <xsl:template match="/ROOT"> 
     <xsl:apply-templates select="E1BPBUSISM008_ITEM_OUT" /> 
    </xsl:template> 

    <xsl:template match="E1BPBUSISM008_ITEM_OUT"> 
     <Ad> 
     <ad-number><xsl:value-of select="ITEM_NUMBER" /></ad-number> 
     <keyword><xsl:value-of select="key('ad2', key('ad1', ITEM_NUMBER)/AD_SPEC_NO)/KEYWORD" /></keyword> 
     </Ad> 
    </xsl:template> 
</xsl:stylesheet> 

Применительно к вашему XML (при условии, ROOT элемент присутствует), следующий выход

<Ad> 
    <ad-number>010</ad-number> 
    <keyword>key1</keyword> 
</Ad> 
<Ad> 
    <ad-number>020</ad-number> 
    <keyword>key2</keyword> 
</Ad> 
+0

+1 для лучшего ответа. –

1

Это всего лишь предложение, потому что я не могу сейчас проходить никакой тест.

Используйте ключ, чтобы получить AD_SPEC_NO от ITEM_NUMBER:

<xsl:key name="AD_SPEC_NO" match="E1BPBUSISM008_ITEM_AD_OUT" use="ITEM_NUMBER"/> 

Тогда, например, в шаблоне сопоставления E1BPBUSISM008_ITEM_OUT, вы можете использовать следующее выражение для получения ключевых слов, связанных значение:

<xsl:value-of select="following-sibling::E1BPBUSISM008_AD_SPEC_AD_OU[ 
     AD_SPEC_NO = key('AD_SPEC_NO',current()/ITEM_NUMBER)/AD_SPEC_NO] 
     /KEYWORD" /> 
Смежные вопросы