Перечислите данный атрибут определенных дочерних элементов - PullRequest
2 голосов
/ 04 января 2009

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

<SEARCHRESULTS>
  <FUNCTION name="BarGraph">
    <PARAMETER name="numList"></PARAMETER>
    <PARAMETER name="maxValue"></PARAMETER>
    <CODE>Some code</CODE>
  </FUNCTION>
</SEARCHRESULTS>

И я хочу извлечь список имен параметров для каждой функции, пока у меня есть следующий код xsl

<xsl:for-each select="SEARCHRESULTS/FUNCTION">
  <ROW>
    <COL><DATA><xsl:value-of select="@name" /></DATA></COL>
    <COL><DATA><xsl:value-of select="PARAMETER/@name" /></DATA></COL>
    <COL><DATA><xsl:value-of select="CODE" /></DATA></COL>
  </ROW>
</xsl:for-each>

, который, конечно, возвращает имя первого параметра вместе с именем и кодом функции.

Я хочу получить список всех параметров функции в текстовой строке. Возврат с разделением лучше, но пока все имена в строке, я могу проанализировать ее позже.

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

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

Полученный XML должен выглядеть как

<ROW>
  <COL><DATA>BarGraph</DATA></COL>
  <COL><DATA>numList;maxValue</DATA></COL>
  <COL><DATA>Some code</DATA></COL>
</ROW>

Где ';' во втором столбце может быть возврат каретки или другой символ, который я могу указать

Ответы [ 4 ]

3 голосов
/ 04 января 2009

Попробуйте со вторым foreach:

<xsl:template match="/">
<xsl:for-each select="SEARCHRESULTS/FUNCTION">
  <ROW>
    <COL>
      <DATA>
        <xsl:value-of select="@name" />
      </DATA>
    </COL>
    <COL>
      <DATA>
        <xsl:for-each select="PARAMETER">
          <!-- separate the names by a semicolon (do not insert a semicolon the first time -->
          <xsl:if test="position() > 1">
            <xsl:text>;</xsl:text>
          </xsl:if>
          <xsl:value-of select="@name" />
        </xsl:for-each>
      </DATA>
    </COL>
    <COL>
      <DATA>
        <xsl:value-of select="CODE" />
      </DATA>
    </COL>
  </ROW>
</xsl:for-each>

2 голосов
/ 05 января 2009

xsl: apply-templates будет вашим ответом. Это просто и элегантно.

<xsl:template match="FUNCTION/PARAMETER">
    <xsl:if test="position() > 1">
        <xsl:text>; </xsl:text> <!-- This is the delimiter -->
    </xsl:if>
    <xsl:value-of select="@name" />
</xsl:template>

Тогда вместо <xsl:value-of select="PARAMETER/@name" /> вы делаете это так:

<xsl:apply-templates select="PARAMETER" />
2 голосов
/ 05 января 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="/*">
      <TABLE>
        <xsl:apply-templates select="*"/>
      </TABLE>
    </xsl:template>
 <!--                                              -->
    <xsl:template match="FUNCTION">
      <ROW>
        <COL><xsl:value-of select="@name"/></COL>
        <COL><xsl:apply-templates select="PARAMETER"/></COL>
        <COL><xsl:apply-templates select="CODE"/></COL>
      </ROW>
    </xsl:template>
 <!--                                              -->
<xsl:template match="PARAMETER">
 <xsl:param name="pDelim" select="';'"/>
 <xsl:value-of select=
 "concat(@name,
         substring($pDelim,
                   1 div not(position() = last()))
                   )"/>
</xsl:template>
</xsl:stylesheet>

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

<SEARCHRESULTS>
    <FUNCTION name="BarGraph">
        <PARAMETER name="numList"></PARAMETER>
        <PARAMETER name="maxValue"></PARAMETER>
        <CODE>Some code</CODE>
    </FUNCTION>
</SEARCHRESULTS>

Требуемый результат получен :

<TABLE>
   <ROW>
      <COL>BarGraph</COL>
      <COL>numList;maxValue</COL>
      <COL>Some code</COL>
   </ROW>
</TABLE>

Обратите внимание , что <xsl:template>, который соответствует PARAMETER, имеет параметр $pDelim, который может использоваться указать, какой символ (или строку) использовать в качестве разделителя для списка имен параметров. Значение по умолчанию для этого разделителя установлено на «;».

1 голос
/ 04 января 2009
<xsl:template match="PARAMETER">
    <xsl:value-of select="@name" />
    <xsl:text> </xsl:text>
</xsl:template>

Заменить текущий код

  <COL><DATA><xsl:value-of select="PARAMETER/@name" /></DATA></COL>

с

  <COL><DATA><xsl:apply-templates select="PARAMETER"/></DATA></COL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...