Как выбрать второй узел, используя xsl: for-each в списке содержимого xml? - PullRequest
1 голос
/ 26 августа 2009

У меня есть список имен фигур и информации о ширине и высоте в отдельном XML-файле,

Мне нужно сопоставить имя фигуры в исходном XML-файле и вставить информацию о ширине и высоте в качестве атрибута в исходный XML-файл.

здесь исходный XML-файл ..

<graphic name="sample.jpg" align="center"/>

ожидаемый выходной файл xml

<graphic name="sample.jpg" width="100" depth="200" align="center"/>

Измерение фигуры xml

<figure>
<name>sample.jpg</name>
<width>100</width>
<height>200</height>
</figure>

Я сохранил значение атрибута имени исходного файла в $ names. И я сохранил значение атрибута имени файла измерения фигуры в '$ figname'.

мой xsl скрипт

<xsl:for-each select="@name">
<xsl:if test="$figname=$name">
<xsl:attribute name="width"><xsl:value-of select="document('figure.xml')/figure/width"/></xsl:attribute>
<xsl:attribute name="depth"><xsl:value-of select="document('figure.xml')/figure/height"/></xsl:attribute>
</xsl:if>
</xsl:for-each>

Это работает только в первый раз, а не для всех. У меня есть почти более 100 изображений. для всех изображений мне нужны значения ширины и высоты. мои скрипты работают только первое значение. как выбрать значение all?

пожалуйста, предложите мне ..

С наилучшими пожеланиями, Antony

----------------------------------------------- --------------------------------------------

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

Я предоставил здесь все подробности для вашего рассмотрения.

ВХОД XML:

<figure>
<title>Earliest Discoveries</title>
<graphic name="luc26959_0101.eps" align="center"/>
<caption>These lithographs of teeth of Iguanodon are from Mantell original 1825 article.</caption>
</figure>

ВВОДНАЯ РИСУНОК XML:

<?xml version="1.0"?>
<figuregroup>
  <figure><name>luc26959_0101.eps</name><width>500</width><height>347</height></figure>
  <figure><name>luc26959_0102.eps</name><width>500</width><height>352</height></figure>
  <figure><name>luc26959_0103.eps</name><width>500</width><height>348</height></figure>
  <figure><name>luc26959_0104.eps</name><width>445</width><height>263</height></figure>
  <figure><name>luc26959_0105.eps</name><width>217</width><height>250</height></figure>
</figuregroup>

ТРАНСФОРМАЦИЯ XSL КОД:

<xsl:template match="graphic">
<xsl:variable name="names">
<xsl:value-of select="substring-before(@name, '.')"/>
</xsl:variable>
<xsl:for-each select="//graphic">
    <imageobject>
        <imagedata>
        <xsl:attribute name="fileref">graphics/<xsl:value-of select="$names"/>.jpg</xsl:attribute>
        <xsl:attribute name="width"><xsl:value-of select="document('../input/fig.xml')/figuregroup/figure[name=$names]/width"/></xsl:attribute>
        <xsl:attribute name="depth"><xsl:value-of select="document('../input/fig.xml')/figuregroup/figure[name=$names]/height"/></xsl:attribute>
        <xsl:apply-templates/>
        </imagedata>
     </imageobject>
</xsl:for-each>
</xsl:template>

ТЕКУЩИЙ ВЫХОД XML:

<figure>
<title>Earliest Discoveries</title>
<mediaobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="" depth=""/></imageobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="" depth=""/></imageobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="" depth=""/></imageobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="" depth=""/></imageobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="" depth=""/></imageobject>
    <caption><para>These lithographs of teeth of <emphasis>Iguanodon</emphasis> are from Mantell's original 1825 article.</para><para/></caption>
</mediaobject>
</figure>

ТРЕБУЕМЫЙ ВЫХОД:

<figure>
<title>Earliest Discoveries</title>
<mediaobject>
    <imageobject><imagedata fileref="graphics/luc26959_0101.jpg" width="500" depth="347"/></imageobject>
    <caption><para>These lithographs of teeth of <emphasis>Iguanodon</emphasis> are from Mantell's original 1825 article.</para><para/></caption>
</mediaobject>
</figure>

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

Я не знаю, как правильно заполнить этот атрибут после использования вашего кода.

Пожалуйста, помогите мне ..

Спасибо и С уважением, Antony

Ответы [ 2 ]

4 голосов
/ 26 августа 2009

В вашем подходе есть ряд ошибок.

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

Во-вторых, <for-each select="@name"> выберет только одну вещь: атрибут name, если он существует, в текущем контексте. Вы, вероятно, хотите что-то вроде <for-each select="//graphic"> вместо.

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

<xsl:attribute name="width">
  <xsl:value-of select="document('figure.xml')//figure[name=$name]/width"/>
</xsl:attribute>

Предполагая, что вы правильно установили $name, о чем я говорил в моем первом пункте.

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

<xsl:template match="/">
  <xsl:for-each select="//graphic">
    <xsl:variable name="name" select="@name"/>
    <xsl:copy>
      <!-- stuff to copy the attributes/children you want, left to the OP -->
      <xsl:attribute name="width">
        <xsl:value-of 
          select="document('figure.xml')//figure[name=$name]/width"/>
      </xsl:attribute>
      <xsl:attribute name="height">
        <xsl:value-of 
          select="document('figure.xml')//figure[name=$name]/height"/>
      </xsl:attribute>
    </xsl:copy>
  </xsl:for-each>
</xsl:template>

EDIT

Одно могу с уверенностью сказать, что вам действительно нужно освежить свои основы XSLT . Проблемы, с которыми вы сталкиваетесь, относительно просты, и в большинстве случаев они основаны на убеждении, что XSLT умнее, чем есть на самом деле. Тем не менее, вот сценарий, который, я считаю, покроет то, что вам нужно:

<xsl:template match="graphic">
  <!-- Get the name of the file in the right dir, with a .jpg extension -->
  <xsl:variable
    name="filename" 
    select="concat('graphics/',substring-before(@name, '.'),'.jpg')"
  />

  <!-- Set a variable to preserve the name of the file we're looking up -->
  <xsl:variable name="lookupname" select="@name"/>

  <!-- Look up this particular figure by name for easy access -->
  <xsl:variable
    name="lookup"
    select="document('../input/fig.xml')/figuregroup/figure[name=$lookupname]"
  />

  <imageobject>
    <imagedata>
    <xsl:attribute name="fileref">
      <xsl:value-of select="$filename"/>
    </xsl:attribute>

    <!-- Set the width and depth according to the lookup variable's children -->
    <xsl:attribute name="width">
      <xsl:value-of select="$lookup/width"/>
    </xsl:attribute>
    <xsl:attribute name="depth">
      <xsl:value-of select="$lookup/height"/>
    </xsl:attribute>

    <!-- Apply any more templates as necessary -->
    <xsl:apply-templates/>
    </imagedata>
  </imageobject>
</xsl:template>
0 голосов
/ 26 августа 2009

Как я понимаю, у вас есть XML-файл с большим количеством различных элементов, и вы хотите добавить ширину и высоту ко всем элементам <graphic...>, не затрагивая остальную часть XML. Я прав? Тогда попробуйте это:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">    
<xsl:output method="xml" indent="yes"/>

<xsl:template match="graphic">
  <xsl:variable name="name" select="@name"/>
  <xsl:copy><xsl:copy-of select="@*"/><xsl:attribute name="width">
    <xsl:value-of select="document('figure.xml')//figure[name=$name]/width"/>
  </xsl:attribute><xsl:attribute name="height">
    <xsl:value-of select="document('figure.xml')//figure[name=$name]/height"/>
  </xsl:attribute></xsl:copy>
</xsl:template>

<xsl:template match="*">
  <xsl:copy><xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="text()"><xsl:copy/></xsl:template>

</xsl:stylesheet>

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

Копирует все элементы и атрибуты как есть (если я не ошибся), но обрабатывает элементы <graphic...> специально, добавляя ширину и высоту, как показано в файле figure.xml. Добавьте больше шаблонов, если вы хотите обрабатывать другие элементы специально, или опустите их.

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