#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}">
Это позволяет избежать необходимости жестко прописывать значимость в вашем соответствующем шаблоне, делая его более универсальным, если вы захотите аналогичным образом сопоставить другие элементы.