Я новичок и все еще учусь XSLT. У меня есть простой XML-код ниже:
<?xml version = "1.0" encoding = "UTF-8"?>
<order id = "1021">
<items>
<item code = "11">
<quantity>2</quantity
<price>50</price>
</item>
<item code = "21">
<quantity>1</quantity>
<price>250</price>
</item>
<item code = "13">
<quantity>4</quantity>
<price>100</price>
</item>
</items>
<status>3</status>
</order>
И я хочу написать сценарий XSLT, который преобразует его в простой текстовый массив, содержащий все коды элементов. Например, приведенный выше XML-код следует преобразовать как: [11,21,13]
Я написал следующий код XSLT:
<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text"/>
<xsl:strip-space elements = "*"/>
<!-- Template to match the root 'order' element -->
<xsl:template match = "/order">
<!-- Start bracket for the array -->
<xsl:text>[</xsl:text>
<!-- Iterate over each item -->
<xsl:for-each select = "items/item">
<!-- Output the code attribute -->
<xsl:value-of select = "@code"/>
<!-- If not the last item, add a comma and space -->
<xsl:if test = "position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<!-- End bracket for the array -->
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
Я столкнулся с проблемой перебора всех элементов. Я получаю только код первого элемента вывода: [11]
Где я ожидаю коды всех предметов, например: [11,21,13]
Пожалуйста, дайте мне знать, если кто-нибудь заметит ошибку в моем коде XSLT. Я пробовал попросить об этом чатгпт, но это не очень помогло.
🤔 А знаете ли вы, что...
XML документ всегда должен иметь корневой элемент, который содержит все остальные элементы.
Ваш XSLT 1.0 отлично работает.
Для сравнения см. ниже, насколько проще это реализовать в XSLT 2.0 и более поздних версиях.
В XSLT 2.0 <xsl:value-of>
был улучшен и теперь имеет атрибут разделителя.
XSLT, 2-е издание, Дуг Тидвелл
Для справки: XSLT
Входной XML
<?xml version = "1.0" encoding = "UTF-8"?>
<order id = "1021">
<items>
<item code = "11">
<quantity>2</quantity>
<price>50</price>
</item>
<item code = "21">
<quantity>1</quantity>
<price>250</price>
</item>
<item code = "13">
<quantity>4</quantity>
<price>100</price>
</item>
</items>
<status>3</status>
</order>
XSLT 1.0
<?xml version = "1.0"?>
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text"/>
<xsl:strip-space elements = "*"/>
<!-- Template to match the root 'order' element -->
<xsl:template match = "/order">
<!-- Start bracket for the array -->
<xsl:text>[</xsl:text>
<!-- Iterate over each item -->
<xsl:for-each select = "items/item">
<!-- Output the code attribute -->
<xsl:value-of select = "@code"/>
<!-- If not the last item, add a comma and space -->
<xsl:if test = "position() != last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
<!-- End bracket for the array -->
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
XSLT 2.0
<?xml version = "1.0"?>
<xsl:stylesheet version = "2.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text"/>
<xsl:template match = "/">
<xsl:text>[</xsl:text>
<xsl:value-of select = "order/items/item/@code"
separator = ", "/>
<xsl:text>]</xsl:text>
</xsl:template>
</xsl:stylesheet>
Выход
[11, 21, 13]