XSLT: преобразовать атрибут в дочерний элемент

#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 родительская оболочка, тогда редактирование должно это исправить.