Пространства имен в XSLT - PullRequest
       19

Пространства имен в XSLT

4 голосов
/ 16 февраля 2009

Я использую XSLT для реструктуризации файла XML. Следующий код копирует все дочерние узлы в новый файл XML:

<!--Add all child elements of the zzz node-->
<xsl:template match="zzz">
    <Trade>
        <xsl:attribute name="ID">
            <xsl:value-of select="TradeId" />
        </xsl:attribute>
        <xsl:copy-of select="*"></xsl:copy-of>
    </Trade>
</xsl:template>

Я хотел бы изменить код так, чтобы он помещал узлы в определенное пространство имен, которого нет в исходном документе. Что мне нужно изменить?

Ответы [ 3 ]

5 голосов
/ 16 февраля 2009

Предыдущие два ответа (теун и Крейг Бовис) неверны - см. Мои комментарии к каждому из них.

Основной способ переместить данный элемент в новое пространство имен заключается в воссоздании этого элемента, как показано ниже :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="zzz">
      <trade ID="{TradeId}">
        <xsl:apply-templates select="*[not(self::TradeId)]"/>
      </trade>
    </xsl:template>

    <xsl:template match="zzz/*">
      <xsl:element name="{name()}" namespace="my:Trade">
        <xsl:copy-of select="@* | node()"/>
      </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к следующему исходному XML-документу :

<zzz>
    <TradeId>153</TradeId>
    <x:item xmlns:x="x:x">A</x:item>
    <x:item xmlns:x="x:x">B</x:item>
    <x:item xmlns:x="x:x">C</x:item>
</zzz>

необходим требуемый результат :

<trade ID="153">
   <x:item xmlns:x="my:Trade">A</x:item>
   <x:item xmlns:x="my:Trade">B</x:item>
   <x:item xmlns:x="my:Trade">C</x:item>
</trade>
0 голосов
/ 16 февраля 2009

Решение Димитра Новатчева в порядке, но я также хотел бы отметить, что если вам нужно изменить пространства имен вложенных элементов, то лучше подойдет следующее:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="zzz">
    <trade ID="{TradeId}">
      <xsl:apply-templates select="*[not(self::TradeId)]" mode="change-ns"/>
    </trade>
  </xsl:template>

  <xsl:template match="@*|node()" priority="-10" mode="change-ns">
    <xsl:copy/>
  </xsl:template>

  <xsl:template match="*" mode="change-ns">
    <xsl:element name="{name()}" namespace="my:Trade">
      <xsl:apply-templates select="@*|node()" mode="change-ns"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

например. если у вас есть следующий входной документ

<trade ID="153">
  <x:item xmlns:x="my:Trade" someattr="1">
    <x:subitem anotherattr="2">A1</x:subitem>
    <x:subitem anotherattr="3">A2</x:subitem>
  </x:item>
  <x:item xmlns:x="my:Trade">B</x:item>
  <x:item xmlns:x="my:Trade">C</x:item>
</trade>

вы получите

<zzz>
  <TradeId>153</TradeId>
  <x:item xmlns:x="x:x" someattr="1">
    <x:subitem anotherattr="2">A1</x:subitem>
    <x:subitem anotherattr="3">A2</x:subitem>
  </x:item>
  <x:item xmlns:x="x:x">B</x:item>
  <x:item xmlns:x="x:x">C</x:item>
</zzz>

Атрибуты добавлены, чтобы продемонстрировать, что они копируются правильно, а отдельный шаблон используется для шаблонов изменения пространства имен, чтобы они не мешали другому коду в случае, если вы хотите использовать их как часть большей таблицы стилей.

0 голосов
/ 16 февраля 2009

Вы можете просто включить пространство имен в свою таблицу стилей следующим образом:

<!--Add all child elements of the zzz node-->
<xsl:template match="zzz" xmlns:my="your target ns">
<my:Trade>
<xsl:attribute name="my:ID" >
<xsl:value-of select="TradeId" />
</xsl:attribute>
<xsl:copy-of select ="*"></xsl:copy-of>
</my:Trade>
</xsl:template>

Редактировать: Как отметил Димитр, не поместит скопированные узлы в новое пространство имен, только в элемент Trade

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