2017-01-31 15 views
1

Я пытаюсь преобразовать выходные данные из источника xml, как показано. Моя попытка показанаXSLT- Преобразование списка повторяющихся элементов с небольшой структурой в упорядоченный список

Вход:

<products> 
    <name>bananas</name> 
    <price>3.55</price> 
    <sku>1223-777-93222</sku> 
    <name>pineapple</name> 
    <price>1.25</price> 
    <sku>013-144-9355</sku> 
</products> 

Ожидаемый результат:

<orders> 
    <order> 
    <name>bananas</name> 
    <price>3.55</price> 
    <item-number>1223-777-93222</item-number> 
    </order> 
    <order> 
    <name>pineapple</name> 
    <price>1.25</price> 
    <item-number>013-144-9355</item-number> 
    </order> 
    </orders> 

XSLT:

 <xsl:choose> 
     <xsl:when test="name"> 
     <order> 
     <name><xsl:value-of select="."/> 
     </xsl:when> 
     <xsl:when test="price"> 
     <price><xsl:value-of select="."/></price> 
     </xsl:when> 
     <xsl:when test="sku"> 
     <item-number><xsl:value-of select="."/></price></item-number> 
     </order> 
     <xsl:when> 
     <xsl:otherwise> 
     </orders> 
     </xsl:otherwise> 

Однако, я не мог заставить его работать. Он не печатает то, что я ожидаю. Я был бы признателен за помощь в преобразовании вывода.

Пожалуйста, помогите, спасибо

+0

Можете ли вы объяснить, Каков ожидаемый результат? – potame

+0

Это то, что ожидалось: бананы 3,55 1223-777-93222 ананаса 1.25 013-144-9355 BreenDeen

+0

Ваш код не должен загружаться. XSL должен быть хорошо сформированным XML, и вы не можете закрыть тэг заказов в теге xsl: иначе. XSL должен использовать рекурсию, а не итеративную или линейную логику. – Mike

ответ

0

Поскольку вы добавили свой вопрос XSLT 2.0, вы можете использовать xsl:for-each-group и group-starting-with ...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="/*"> 
    <orders> 
     <xsl:for-each-group select="*" group-starting-with="name"> 
     <order> 
      <xsl:apply-templates select="current-group()"/> 
     </order> 
     </xsl:for-each-group> 
    </orders> 
    </xsl:template> 

    <xsl:template match="sku"> 
    <item-number> 
     <xsl:apply-templates/> 
    </item-number> 
    </xsl:template> 

</xsl:stylesheet> 

EDIT: Бесполезный Не заметите, что хотите изменить вывод sku.

+0

Спасибо, очень благодарен! – BreenDeen

0

Предполагая, что ваш вход регулярно (т.е. каждый элемент представлен точно такой же трех элементов, в том же порядке), вы можете сделать просто:

XSLT 1,0

<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:strip-space elements="*"/> 

<xsl:template match="/products"> 
    <orders> 
     <xsl:for-each select="name"> 
      <order> 
       <xsl:copy-of select=". | following-sibling::price[1]"/> 
       <item-number> 
        <xsl:value-of select="following-sibling::sku[1]"/> 
       </item-number> 
      </order> 
     </xsl:for-each> 
    </orders> 
</xsl:template> 

</xsl:stylesheet>