Не удалось создать вложенные элементы в XML с помощью XLST - PullRequest
2 голосов
/ 08 июня 2011

У меня плоский XML, который выглядит так:

<objectDataList>
<objectData>
    <equipment>
        <name>Chassis-One</name>
        <type>Chassis</type>
    </equipment>
</objectData>
<objectData>
    <equipment>
        <name>Shelf-One</name>
        <type>Shelf</type>
    </equipment>
</objectData>
<objectData>
    <equipment>
        <name>Shelf-Two</name>
        <type>Shelf</type>
    </equipment>
</objectData>
<objectData>
    <equipment>
        <name>Slot-One</name>
        <type>Slot</type>
    </equipment>
</objectData>

Как я могу создать XSL, который преобразует мой XML в другой XML, который выглядит следующим образом:

<equipments>
<object>
    <name>Chassis-One</name>
        <object>
            <name>Shelf-One</name>
            <object>
                <name>Slot-One</name>
            </object>
        </object>

</object>

Это как в шасси, есть 2 полки, а на Полке 1 есть слот - один ..

Я попробовал наполовину, но не мог придумать, как сделать вложенный элемент:

<xsl:template match="/response">
    <equipments>            
            <object>
                <xsl:apply-templates select="objectData"/>
            </object>
    </equipments>

<xsl:template match="objectData/equipment[type='Chassis']">
    <name><xsl:value-of select="equipment/name"/></name>
        <!-- Now I want to find the shelf according to the chassis name -->
        <xsl:call-template name="find-shelf-according-to-chasis-name">
            <xsl:with-param name="chassisName" select="equipment/name"/>
        </xsl:call-template>
</xsl:template>

Я надеюсь, что кто-то может пролить свет

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 08 июня 2011

Существует довольно простое (хотя и несколько подробное) решение:

<xsl:template match="objectDataList">
  <equipments>
    <xsl:apply-templates select="objectData[equipment/type='Chassis']"/>
  </equipments>
</xsl:template>

<xsl:template match="objectData[equipment/type='Chassis']">
  <xsl:variable name="index" select="substring-after(equipment/name,'-')" />
  <object>
    <xsl:copy-of select="equipment/name" />
    <xsl:apply-templates select="following-sibling::objectData[equipment/type='Shelf' and substring-after(equipment/name,'-') = $index]" />
  </object>
</xsl:template>

<xsl:template match="objectData[equipment/type='Shelf']">
  <xsl:variable name="index" select="substring-after(equipment/name,'-')" />
  <object>
    <xsl:copy-of select="equipment/name" />
    <xsl:apply-templates select="following-sibling::objectData[equipment/type='Slot' and substring-after(equipment/name,'-') = $index]" />
  </object>
</xsl:template>

<xsl:template match="objectData[equipment/type='Slot']">
  <xsl:variable name="index" select="substring-after(equipment/name,'-')" />
  <object>
    <xsl:copy-of select="equipment/name" />
  </object>
</xsl:template>

Хотя это немного повторяется, последние три шаблона почти идентичны.Но тогда, в зависимости от ваших конкретных требований, может быть полезно, чтобы они обрабатывались различными шаблонами.

Если вы можете гарантировать, что полка всегда будет следовать за соответствующим шасси и т. Д., То вы можете изменить <xsl:apply-templates во втором шаблоне:

<xsl:apply-templates select="following-sibling::*[1]">

Если его может не быть, вы можете сделать:

<xsl:apply-templates select="following-sibling::*[1][equipment/type='Shelf']">

0 голосов
/ 08 июня 2011

Следующий скрипт будет делать то, что вы хотите, он немного длинен из-за того, что структура Chassis - Shelf - Slot должна быть представлена ​​в скрипте.Если ваш xml будет содержать атрибуты id и parent-id, сценарий может быть меньше, а соглашение об именовании может быть удалено или ослаблено.

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

  <xsl:output method="xml"/>

  <xsl:template match="/">
    <equipments>
    <xsl:apply-templates select="//equipment[type='Chassis']" />
    </equipments>
  </xsl:template>

  <xsl:template match="equipment[type='Chassis']">
    <xsl:variable name="suffix" select="substring-after(name, '-')" />
    <object>
        <xsl:copy-of select="name" />
        <xsl:apply-templates select="//equipment[type='Shelf'][substring-after(name, '-')=$suffix]" />
    </object>
  </xsl:template>


  <xsl:template match="equipment[type='Shelf']">
    <xsl:variable name="suffix" select="substring-after(name, '-')" />
    <object>
        <xsl:copy-of select="name"/>
        <xsl:apply-templates select="//equipment[type='Slot'][substring-after(name, '-')=$suffix]" />
    </object>
  </xsl:template>

  <xsl:template match="equipment[type='Slot']">
    <object>
        <xsl:copy-of select="name"/>
    </object>
  </xsl:template>

</xsl:stylesheet>

Запрашиваемая деталь использует функцию substring-after для определениясуффикс имени и использует его в последующем выборе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...