Применить XSLT Transform к уже преобразованному XML - PullRequest
5 голосов
/ 09 сентября 2010

Все,

У меня есть файл XML, который я преобразую с помощью документа XSLT в другой XML.

Могу ли я определить другой набор преобразований в том же файле XSLT, который будет применяться в XML-результате первого преобразования?

Спасибо

MK

1 Ответ

9 голосов
/ 09 сентября 2010

Да.

I.Это преобразование XSLT 1.0 :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vrtfPass1">
  <xsl:apply-templates/>
 </xsl:variable>

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

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

 <xsl:template match="num/text()">
  <xsl:value-of select="2*."/>
 </xsl:template>

 <xsl:template match="num/text()" mode="pass2">
  <xsl:value-of select="1+."/>
 </xsl:template>

 <xsl:template match="/">
  <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
 </xsl:template>
</xsl:stylesheet>

при применении к этому документу XML :

<t>
 <num>1</num>
 <num>2</num>
 <num>3</num>
 <num>4</num>
 <num>5</num>
</t>

создает :

<t>
    <num>3</num>
    <num>5</num>
    <num>7</num>
    <num>9</num>
    <num>11</num>
</t>

Примечание :

  1. Два преобразования фактически выполняются , второе выполняется по результату первого.

  2. Результатом первого преобразования является содержимое переменной $vrtfPass1.

  3. В XSLT 1.0 тип переменныхкоторые содержат динамически генерируемые (временные) деревья XML (документ XML или фрагмент XML) - это RTF (Result-Tree-Fragment).Операции XPath невозможны с RTF - его необходимо преобразовать в обычный набор узлов с помощью функции расширения xxx:node-set(), которая предоставляется подавляющим большинством поставщиков процессоров XSLT 1.0.В этом примере используется exslt: node-set (), поскольку EXSLT реализуется многими различными поставщиками.

  4. Второе преобразование применяется к результату первого : <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>.Отдельный mode используется для четкого разделения кода двух преобразований.

  5. Первое преобразование умножает каждое num/text() на 2. Второе преобразование увеличивает каждоеnum/text().Результат: 2*.+1

II.Это преобразование XSLT 2.0 :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vPass1">
  <xsl:apply-templates mode="pass1"/>
 </xsl:variable>

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

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

 <xsl:template match="num/text()" mode="pass1">
  <xsl:value-of select="2*xs:integer(.)"/>
 </xsl:template>

 <xsl:template match="num/text()" mode="pass2">
  <xsl:value-of select="1+."/>
 </xsl:template>

 <xsl:template match="/">
  <xsl:apply-templates select="$vPass1"  mode="pass2"/>
 </xsl:template>
</xsl:stylesheet>

при применении к тому же XML-документу дает тот же требуемый и правильный результат .

Примечание: В XSLT 2.0 / XPath 2.0 тип RTF отменен.Нет необходимости в расширении xxx:node-set().

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