Как решить проблему XML в XML с помощью Exslt - set: Different - PullRequest
1 голос
/ 26 января 2010

Это распространяется от XML до XML с использованием XSL Problem Мне удалось импортировать exslt и изменить мои коды в соответствии с решением (благодаря Кайлу Батту), приведенному ниже:

<xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:func="http://exslt.org/functions"
              xmlns:set="http://exslt.org/sets"
              extension-element-prefixes="set">

<xsl:import href="set.distinct.function.xsl"/>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <xsl:value-of select="."/>
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/object[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

Но есть ошибка в выходных данных, которая гласит: «Функция set: different () завершилась ошибкой. Значение не может быть нулевым. Как это решить?

Кстати, ввод XML:

<gallery>
  <photo>
    <tag>
      <event>Birthday</event>
      <group>Family</group>
      <other>Swensens</other>
    </tag>
  </photo>
  <photo>..</photo>
</gallery>

& Требуемый вывод XML:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
         <other>Swensens</other>
        </tag>
      </photo>
      <photo>..</photo>
    </group>
    <group>..</group>
  </event>
  <event>..</event>
</gallery>

1 Ответ

0 голосов
/ 31 января 2010

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

<gallery>
  Birthday
  <event name="Birthday"/>
</gallery>

Так что здесь происходит ряд вещейкоторые не приводят вас к выводу, который вы хотите.Во-первых, вы просто выводите имя события в качестве значения узла галереи, поэтому, чтобы избавиться от него, вы захотите удалитьв первом xsl: for-each (возможно, был оставлен этот код отладки?)

Затем рассмотрим эту часть в xsl: for-each для событий:

<xsl:variable name="event" select="." />
<xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">

Я вижу несколько проблем с XPath в наборе: Different:

  1. Узел под узлом галереи в XML-вводе, который вы дали, - , и в вашем XPath у вас есть объект.".
  2. Вы не используете переменную $ event для проверки узла события - предикат для тега должен быть [event = $ event].

Это то, что способствуетк ошибке, которую вы видите - XPath ничего не выбирает, поэтому вы вызываете set: Different on null.

Итак, с учетом этих исправлений получаю вывод:

<gallery>
  <event name="Birthday">
    <group name="Family"/>
  </event>
</gallery>

Тогда XPath вТакже необходимо изменить объект на фотографию.В свою таблицу стилей я добавил шаблон, который соответствует фотографии, так как он не был включен в ваш образец таблицы стилей, поэтому моя таблица стилей теперь выглядит следующим образом:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:func="http://exslt.org/functions"
          xmlns:set="http://exslt.org/sets"
          extension-element-prefixes="set">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/photo/tag[event=$event]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/photo[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

<xsl:template match="photo">
  <photo>
    <tag>
      <xsl:copy-of select="tag/*[not(name(.)='group') and not(name(.)='event')]" />
    </tag>
  </photo>
</xsl:template>
</xsl:stylesheet>

и получаю вывод:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
          <other>Swensens</other>
        </tag>
      </photo>
    </group>
  </event>
</gallery>

Тад !!

...