XSLT скопировать с изменением

kot_k_k

Новичок
Добрый день, такая загвоздка.
Есть XSLT - копирует XML и изменяет один тег. Все работает ура.
Но теперь возникла необходимость изменить тег, которого может быть несколько, циклом.
но при вставке цикла в обработку - он или не обрабатывает или валит все теги в месте.
вот XSLT
Код:
<xsl:template match="/">
<xsl:for-each select="/ORDER/HEAD/POSITION">       
            <PRODUCT>
            <xsl:if test="PRODUCT!=''">
                    <xsl:value-of select="PRODUCT"/>
            </xsl:if>
            <xsl:if test="not(PRODUCT)">
                    <xsl:value-of select="PRODUCTIDBUYER"/>
            </xsl:if>
            </PRODUCT>
</xsl:for-each>
</xsl:template> 
    <xsl:template match="/ | @* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
в этом случае ничего не изменяет.
если изменить в начале
<xsl:template match="/">
на
<xsl:template match="PRODUCT">
то будет нанизывать все значения поля продукт и выдавать каждый раз нет такое
<PRODUCT>36830</PRODUCT><PRODUCT>777777</PRODUCT><PRODUCT>11140252353</PRODUCT>

как правильно это сделать - чтобы скопировало все, но отработал цикл на изменение.
Конечно можно тупо переписать всю карту и вставить цикл, но хочется красоты:rolleyes:
 

WMix

герр M:)ller
Партнер клуба
нарисуй короткий xml и xsl который работает на 1 элемент
 

kot_k_k

Новичок
Вот такой XML
Код:
<ORDER>
    <DOCUMENTNAME>220</DOCUMENTNAME>
    <HEAD>
    <SR>74858965655</SR>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
    </HEAD>
</ORDER>
ну и XSL (цикл я уже добавил - но видимо криво)
Код:
<xsl:template match="PRODUCT">
<xsl:for-each select="/ORDER/HEAD/POSITION">      
            <PRODUCT>
            <xsl:if test="PRODUCT!=''">
                    <xsl:value-of select="PRODUCT"/>
            </xsl:if>
            <xsl:if test="not(PRODUCT)">
                    <xsl:value-of select="PRODUCTIDBUYER"/>
            </xsl:if>
            <xsl:if test="PRODUCT=''">
                    <xsl:value-of select="PRODUCTIDBUYER"/>
            </xsl:if>
            </PRODUCT>
</xsl:for-each>
</xsl:template>

    <xsl:template match="/ | @* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
а теперь решили что их будет много

Код:
<ORDER>
    <DOCUMENTNAME>220</DOCUMENTNAME>
    <HEAD>
    <SR>74858965655</SR>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>77477474</PRODUCTIDBUYER>
        </POSITION>
    </HEAD>
</ORDER>
вот тут и затыка - получаю вот такое сщазтье.

Код:
<ORDER>
    <DOCUMENTNAME>220</DOCUMENTNAME>
    <HEAD>
    <SR>74858965655</SR>
        <POSITION>
            <POSITIONNUMBER>1</POSITIONNUMBER>
            <PRODUCT>36830</PRODUCT><PRODUCT>77477474</PRODUCT>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>36830</PRODUCT><PRODUCT>77477474</PRODUCT>
            <PRODUCTIDBUYER>77477474</PRODUCTIDBUYER>
        </POSITION>
    </HEAD>
</ORDER>
п.с. - видимо лыжи и асфальт:)
 

WMix

герр M:)ller
Партнер клуба
можно полностью рабочий xls не обрывок! (и желательно ожидаемый результат)
а вообще и так видно что ты на каждый продукт лезешь вверх по дереву на все позиции
 
Последнее редактирование:

kot_k_k

Новичок
Он весь, вот такой. Я только хотел обернуть в цикл обработку PRODUCT - но фокус не удался

Код:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="PRODUCT">      
            <PRODUCT>
            <xsl:if test="/ORDER/HEAD/POSITION/PRODUCT!=''">
                    <xsl:value-of select="/ORDER/HEAD/POSITION/PRODUCT"/>
            </xsl:if>
            <xsl:if test="/ORDER/HEAD/POSITION/PRODUCT=''">
                    <xsl:value-of select="/ORDER/HEAD/POSITION/PRODUCTIDBUYER"/>
            </xsl:if>
            </PRODUCT>
</xsl:template>
    <xsl:template match="/ | @* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
 

kot_k_k

Новичок
Файл с одним тегом:

Код:
<ORDER>
    <DOCUMENTNAME>220</DOCUMENTNAME>
    <HEAD>
    <SR>74858965655</SR>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
    </HEAD>
</ORDER>
Обрабатывает нормально
Код:
<ORDER>
    <DOCUMENTNAME>220</DOCUMENTNAME>
    <HEAD>
    <SR>74858965655</SR>
        <POSITION>
            <PRODUCT>36830</PRODUCT>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
    </HEAD>
</ORDER>
а с двумя позициями и более, то получаем в поле PRODUCT в место одного - все поля :
.....
<POSITION>
<PRODUCT>36830</PRODUCT><PRODUCT>77477474</PRODUCT>.... сколько ни есть позиций .....</PRODUCT>
<PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
.....
как и писал.
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
вот как тебе обьяснить? хочется помочь, не понимаю чем!
чтоб я мог тебе помочь, я должен понимать что я должен получить, и из чего. из чего я уже видел, вопрос что должно получиться? соберись уже и нарисуй 3 xml. изначальный, шаблон (который не до конца работает, но с 1 продуктом работает), и РЕЗУЛЬТАТ обработки (- что ты хочешь получить)
если из 5 продуктов остается один, то какой (по каким признакам брать его).

PHP:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="POSITION">      
        <POSITION>
            <PRODUCT><xsl:value-of select="PRODUCTIDBUYER" /></PRODUCT>
            <xsl:apply-templates select="*[not(local-name() = 'PRODUCT')]" />
        </POSITION>
    </xsl:template>

    <xsl:template match="/ | @* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
 
Последнее редактирование:

kot_k_k

Новичок
Спасибо за заботу!
Блоков POSITION - может быть много
в них есть поле PRODUCT - оно может быть, а может не быть, если нет, то ему присваиваем значение поля PRODUCTIDBUYER.
Поле PRODUCTIDBUYER просто копируется.
т.е. если вот такое на входе:
Код:
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>7412058</PRODUCT>
            <PRODUCTIDBUYER>8899888</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>41415252</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT/>
            <PRODUCTIDBUYER>11111000</PRODUCTIDBUYER>
        </POSITION>
на выходе должны получить:
Код:
        <POSITION>
            <PRODUCT>36830</PRODUCT>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>7412058</PRODUCT>
            <PRODUCTIDBUYER>8899888</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>41415252</PRODUCT>
            <PRODUCTIDBUYER>41415252</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>11111000</PRODUCT>
            <PRODUCTIDBUYER>11111000</PRODUCTIDBUYER>
        </POSITION>
т.е. надо скопировать все поля - и сделать проверку на одно поле PRODUCT, которых может быть неизвестное количество.

а получается вот такое, длинное и не нужное

Код:
        <POSITION>
            <PRODUCT>36830</PRODUCT><PRODUCT>7412058</PRODUCT><PRODUCT>41415252</PRODUCT><PRODUCT>11111000</PRODUCT>
            <PRODUCTIDBUYER>36830</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>36830</PRODUCT><PRODUCT>7412058</PRODUCT><PRODUCT>41415252</PRODUCT><PRODUCT>11111000</PRODUCT>
            <PRODUCTIDBUYER>8899888</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>36830</PRODUCT><PRODUCT>7412058</PRODUCT><PRODUCT>41415252</PRODUCT><PRODUCT>11111000</PRODUCT>
            <PRODUCTIDBUYER>41415252</PRODUCTIDBUYER>
        </POSITION>
        <POSITION>
            <PRODUCT>36830</PRODUCT><PRODUCT>7412058</PRODUCT><PRODUCT>41415252</PRODUCT><PRODUCT>11111000</PRODUCT>
            <PRODUCTIDBUYER>11111000</PRODUCTIDBUYER>
        </POSITION>


еще раз спасибо за участие.
 

WMix

герр M:)ller
Партнер клуба
PHP:
    <xsl:template match="PRODUCT">     
        <PRODUCT>
            <xsl:choose>
                <xsl:when test=".=''">
                    <xsl:value-of select="../PRODUCTIDBUYER" />
                </xsl:when>
                <xsl:otherwise>
                   <xsl:value-of select="." />
                </xsl:otherwise>
            </xsl:choose>
        </PRODUCT>
    </xsl:template>
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
твоя ошибка что ты начинаешь копать от корня, а надо относительно, я поправил
 

kot_k_k

Новичок
Огромное спасибо.
ТО что надо - работает!!!!

Ошибка в том что практически не знаю XSLT, все VBA да VBA.
 

AnrDaemon

Продвинутый новичок
Честно? Нет. Где-то до середины осилил все примеры, потом появились другие интересы. Но я не оставляю надежды вернуться и дочитать/доделать.
 

WMix

герр M:)ller
Партнер клуба
у меня страниц 20-50 типа введение и один прожектик, где мы вьюшки генерили
 
Сверху