Получить одно значение из нескольких значений атрибутов XML с помощью xslt - PullRequest
2 голосов
/ 17 февраля 2012

У меня есть xml, и я хочу атрибут, который определен в «заголовке» с использованием файла XSL. Я хочу получить значение стиля и значения "abc" и "cdf"

<catalog>
    <cd>
       <title style="abc:true;cdf:false"  att2="false">Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

я попробовал это

 <td><xsl:value-of select="substring-before(substring-after(@style,'abc:'),';')"/></td>

Ответы [ 3 ]

3 голосов
/ 17 февраля 2012

Это общее преобразование, которое позволяет обрабатывать строку, содержащую неопределенное количество пар имя-значение :

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

 <xsl:template match="/">
  <xsl:variable name="vStyle" select="/*/*/title/@style"/>

  The value for 'abc' is : <xsl:text/>
  <xsl:call-template name="getValueOfName">
   <xsl:with-param name="pText" select="$vStyle"/>
   <xsl:with-param name="pName" select="'abc'"/>
  </xsl:call-template>

  The value for 'cdf' is : <xsl:text/>
  <xsl:call-template name="getValueOfName">
   <xsl:with-param name="pText" select="$vStyle"/>
   <xsl:with-param name="pName" select="'cdf'"/>
  </xsl:call-template>


  The value for 'xyz' is : <xsl:text/>
  <xsl:call-template name="getValueOfName">
   <xsl:with-param name="pText" select="$vStyle"/>
   <xsl:with-param name="pName" select="'xyz'"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="getValueOfName">
  <xsl:param name="pText"/>
  <xsl:param name="pName"/>

  <xsl:choose>
      <xsl:when test="not(string-length($pText) > 0)"
        >***Not Found***</xsl:when>
      <xsl:otherwise>
        <xsl:variable name="vPair" select=
         "substring-before(concat($pText, ';'), ';')"/>

         <xsl:choose>
           <xsl:when test=
           "$pName = substring-before(concat($vPair, ':'), ':')">

             <xsl:value-of select="substring-after($vPair, ':')"/>
           </xsl:when>
           <xsl:otherwise>
             <xsl:call-template name="getValueOfName">
               <xsl:with-param name="pText" select=
                  "substring-after($pText, ';')"/>
               <xsl:with-param name="pName" select="$pName"/>
             </xsl:call-template>
           </xsl:otherwise>
         </xsl:choose>
      </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<catalog>
    <cd>
        <title style="abc:true;cdf:false"  att2="false">Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

дает желаемый результат :

  The value for 'abc' is : true

  The value for 'cdf' is : false


  The value for 'xyz' is : ***Not Found***

Объяснение

Шаблон getValueOfName является универсальным шаблоном, который находит пару имя-значение, содержащее указанное pName, а затем выводит значение - или, если это имя вообще не найдено, выводится строка ***Not Found*** .

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

2 голосов
/ 17 февраля 2012

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

Если вы используете XPath 2.0, вы можете использовать вызов функции (например, substring-after, substring-before) дляправо оператора /.Так что это будет работать:

/catalog/cd/title/substring-before(substring-after(@style,'abc:'),';')

В XPath 1.0 вы не можете сделать это, вещь справа от каждого / должна быть шагом оси (а не вызовом функции), поэтому вам придется использовать:

substring-before(substring-after(/catalog/cd/title/@style,'abc:'),';') 
1 голос
/ 17 февраля 2012

Я думаю, что вы близко:

  <!-- abc -->
  <xsl:value-of 
       select="substring-after(
               substring-before(/catalog/cd/title/@style,';'),'abc:')"/>
  <!-- cdf -->
 <xsl:value-of 
      select="substring-after(
              substring-after(/catalog/cd/title/@style,';'),'cdf:')"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...