#xml #xslt
#xml #xslt
Вопрос:
Я новичок в XSLT, и хотя преобразование XML в HTML вполне выполнимо, я борюсь с преобразованием XML в XML. То, что я хочу сделать, должно быть довольно простым, но я безнадежно застрял. Рассмотрим этот XML-файл:
<cookbook xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://jg.dhlab.de/Teaching/recipe.xsd">
<recipe name="Apple pie">
<ingredients name='Apples'/>
<ingredients name='Butter'/>
<ingredients name="Flour"/>
<ingredients name="Cinnamon"/>
<ingredients name="Sugar"/>
<ingredients name="Eggs"/>
<instructions>In a small bowl, combine the sugars, flour and spices; set aside. In a large bowl, toss apples with lemon juice. Add sugar mixture; toss to coat. Line a 9-in. pie plate with bottom crust; trim even with edge. Fill with apple mixture; dot with butter. Roll remaining crust to fit top of pie; place over filling. Trim, seal and flute edges. Cut slits in crust.
Beat egg white until foamy; brush over crust. Sprinkle with sugar. Cover edges loosely with foil. Bake at 375° for 25 minutes. Remove foil and bake until crust is golden brown and filling is bubbly, 20-25 minutes longer. Cool on a wire rack.</instructions>
</recipe>
</cookbook>
Я хочу преобразовать атрибут name элемента ingredients в дочерний элемент (т. Е. С сохранением элемента ingredients. XSL, который я использую:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ingredients">
<xsl:element name="{name(@name)}">
<xsl:value-of select="@name"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Однако этот XSL преобразует атрибут name в элемент, но переопределяет элемент ingredients . Я хотел бы получить следующий результат:
<recipe name="Apple pie">
<ingredients>
<name>Apples</name>
<name>Butter</name>
<name>Flour</name>
<name>Cinnamon</name>
<name>Sugar</name>
<name>Eggs</name>
</ingredients>
<instructions>In a small bowl, combine the sugars, flour and spices; set aside. In a large bowl, toss apples with lemon juice. Add sugar mixture; toss to coat. Line a 9-in. pie plate with bottom crust; trim even with edge. Fill with apple mixture; dot with butter. Roll remaining crust to fit top of pie; place over filling. Trim, seal and flute edges. Cut slits in crust.
Beat egg white until foamy; brush over crust. Sprinkle with sugar. Cover edges loosely with foil. Bake at 375° for 25 minutes. Remove foil and bake until crust is golden brown and filling is bubbly, 20-25 minutes longer. Cool on a wire rack.</instructions>
</recipe>
Кто-нибудь может сказать мне, как этого добиться и что я делаю не так?
Ответ №1:
Если вы знаете, что хотите создавать name
элементы, затем используйте <name><xsl:value-of select="@name"/></name>
в шаблоне with match="ingredients"
.
для создания элемента-оболочки используйте, например
<xsl:template match="recipe">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:where-populated>
<ingredients>
<xsl:apply-templates select="ingredients"/>
</ingredients>
</xsl:where-populated>
<xsl:apply-templates select="* except ingredients"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ingredients">
<name>
<xsl:value-of select="@name"/>
</name>
</xsl:template>
Комментарии:
1. Я пробовал это, но по какой-то причине я получаю этот результат:
<recipe name="Apple pie"> <name>Apples</name> <name>Butter</name> <name>Flour</name> <name>Cinnamon</name> <name>Sugar</name> <name>Eggs</name> <instructions>In a small bowl, combine the sugars....</instructions>
</рецепт>2. @Jaap, смотрите Редактирование, если преобразование в
name
элементы выполняется по мере необходимости, и единственной отсутствующей проблемой являетсяingredients
родительская оболочка, тогда редактирование должно это исправить.