Получение определенных значений из xml с помощью xsl

#xslt

#xslt

Вопрос:

У меня есть xml, как показано ниже.

 <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet> 
  

Ответ №1:

Это полное, но короткое и простое преобразование:

 <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="attributeName[.='salience']">
  <salience>
   <xsl:value-of select="../value"/>
  </salience>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
  

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

 <attributes>
    <attribute>
        <attributeName>agenda-group</attributeName>
        <value>common</value>
    </attribute>
    <attribute>
        <attributeName>auto-focus</attributeName>
        <value>true</value>
    </attribute>
    <attribute>
        <attributeName>no-loop</attributeName>
        <value>true</value>
    </attribute>
    <attribute>
        <attributeName>salience</attributeName>
        <value>73</value>
    </attribute>
</attributes>
  

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

 <salience>73</salience>
  

Комментарии:

1. Я попробовал описанный выше подход. Но у меня это не работает. Но я попробовал приведенное ниже решение, которое работает для меня, но не знаю, оптимизировано ли это решение или нет. Мы будем признательны за вашу помощь. Пожалуйста, найдите мое решение ниже

2. @srinivas: Просто скопируйте и вставьте преобразование, затем запустите его в предоставленном вами XML-документе — вы должны получить желаемый результат.

Ответ №2:

Попробуйте это:

   <xsl:template match="attributes/attribute">
    <xsl:if test=".//attributeName='salience'">
      <xsl:value-of select=".//value"/>
    </xsl:if>
  </xsl:template>
  

P.S. Пожалуйста, отформатируйте свой пост, так как XSL не отображается.

Комментарии:

1. Вышеупомянутое решение не работает. Я ничего не получаю в выходном файле.

2. Примите к сведению <xsl:template match="attributes/attribute"> . Это отличается от того, что у вас есть. Я пробовал это, и это сработало. Пожалуйста, дважды проверьте, как вы это реализовали.

Ответ №3:

Основная проблема заключается в этом операторе xsl:if

 <xsl:if test="//attributes//attribute[(attributeName = 'salience')]">
  

На данный момент контекст по-прежнему является корневым узлом, поэтому все, что это делает, это проверяет существование элемента attibute, вы фактически не позиционируете себя на узле. Таким образом, когда вы выполняете xsl:value-of, вы просто получаете первое значение в XML.

Вместо использования xsl:if вам, вероятно, следует попробовать сопоставить элемент attribute следующим образом

 <xsl:apply-templates select="attributes/attribute[attributeName = 'salience']"/>
  

Весь XSLT был бы следующим

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/">
      <xsl:apply-templates select="attributes/attribute[attributeName = 'salience']"/>
   </xsl:template>
   <xsl:template match="attribute">
      <xsl:element name="{attributeName}">
         <xsl:value-of select="value"/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>
  

При применении к вашему входному XML результат выглядит следующим образом:

 <salience>73</salience>
  

Обратите внимание на использование xsl:element

 <xsl:element name="{attributeName}">
  

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