Как использовать XSL для добавления нового элемента на уровне определенного дочернего узла? - PullRequest
2 голосов
/ 25 октября 2011

Я пытаюсь помочь другу решить викторину по компьютерному классу. У меня есть простой XML-файл, который определяет названия DVD, которые у меня есть на полке ...

<Inventory>
    <DVD>
        <Name>Captain America</Name>
    </DVD>
    <DVD>
        <Name>Green Lantern</Name>
    </DVD>
    <DVD>
        <Name>Thor</Name>
    </DVD>
</Inventory>

Допустим, «Капитан Америка» и «Тор» извлечены, а «Зеленый фонарь» еще доступен. Я хотел бы преобразовать указанный выше XML-файл в следующий XML ...

<Inventory>
    <DVD>
        <Name>Captain America</Name>
        <Status>Checked-Out</Status>
    </DVD>
    <DVD>
        <Name>Green Lantern</Name>
        <Status>Available</Status>
    </DVD>
    <DVD>
        <Name>Thor</Name>
        <Status>Checked-Out</Status>
    </DVD>
</Inventory>

Может кто-нибудь поделиться, как использовать XSL для добавления элемента Status в каждый узел? У меня есть только фрагмент кода ниже, но он копирует один и тот же элемент для всех узлов.

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

<xsl:template match="DVD">
    <xsl:copy>
        <xsl:copy-of select="@*|node()"/>
        <Status>Checked-Out</Status>
    </xsl:copy>
</xsl:template>

Спасибо, очень, очень, очень ...

1 Ответ

4 голосов
/ 25 октября 2011

Что вы можете сделать, это использовать xsl:param для передачи названий DVD-дисков, которые были извлечены, на ваш XSL и добавить <status> на основе этого. Используя xsl:param, вы можете передать значение из командной строки.

Вот пример XSLT 2.0, в котором имена DVD-дисков разделены символом "*" в xsl:param. Я использую tokenize() в моем xsl:template match, чтобы эти DVD-диски получили статус «Выписан». Все остальные DVD получат статус «Доступен».

Таблица стилей 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:param name="checkedOut" select="'Captain America|Thor'"/>

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

  <xsl:template match="DVD[Name=tokenize($checkedOut,'\|')]">
    <xsl:copy>
      <xsl:apply-templates/>
      <status>Checked-Out</status>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="DVD">
    <xsl:copy>
      <xsl:apply-templates/>
      <status>Available</status>
    </xsl:copy>
  </xsl:template>  

</xsl:stylesheet>

применительно к вашему примеру XML выдает следующий вывод:

<Inventory>
   <DVD>
      <Name>Captain America</Name>
      <status>Checked-Out</status>
   </DVD>
   <DVD>
      <Name>Green Lantern</Name>
      <status>Available</status>
   </DVD>
   <DVD>
      <Name>Thor</Name>
      <status>Checked-Out</status>
   </DVD>
</Inventory>

Надеюсь, это поможет.

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