#xml #xslt-1.0 #xslt-2.0
#xml #xslt-1.0 #xslt-2.0
Вопрос:
Я пытаюсь преобразовать следующий XML
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd QualifyingCode="1">
<title>title1</title>
<artist>artist1</artist>
</cd>
<cd QualifyingCode="1">
<title>title2</title>
<artist>artist2</artist>
</cd>
<cd QualifyingCode="2">
<title>title3</title>
<artist>artist3</artist>
</cd>
<cd QualifyingCode="2">
<title>title4</title>
<artist>artist4</artist>
</cd>
</catalog>
Использование floowing XSLT
<?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 style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
<th style="text-align:left">ID</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="position()"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Я получаю позицию как 1,2,3,4, используя position (). Я хочу, чтобы вывод для position () был 1,2,1,2 на основе атрибута «QualifyingCode».
итак, мой текущий результат :
My CD Collection
Title Artist ID
title1 artist1 1
title2 artist2 2
title3 artist3 3
title4 artist4 4
и мой ожидаемый результат
My CD Collection
Title Artist ID
title1 artist1 1
title2 artist2 2
title3 artist3 1
title4 artist4 2
Ответ №1:
Одним из способов является использование
<td><xsl:value-of select="count(preceding-sibling::cd[@QualifyingCode = current()/@QualifyingCode]) 1"/></td>
Комментарии:
1. будет ли это работать, если код уточнения не имеет приращения 1? допустим, у меня есть код уточнения как «25» и «8»
2. Выражение
count(preceding-sibling::cd[@QualifyingCode = current()/@QualifyingCode])
подсчитывает количество предшествующих родственныхcd
элементов, которые имеют то жеQualifyingCode
значение атрибута, что и контекстный узел (который являетсяcd
элементом, обработаннымfor-each
или сопоставленным шаблоном). Итак, да, предполагая, что вы хотите посчитать элементы, имеющие одинаковое значение, это работает.
Ответ №2:
Я хочу, чтобы вывод для position () был 1,2,1,2 на основе атрибута «QualifyingCode».
Это недостаточно четкое требование, и пример тоже неоднозначен. Предполагая, что вы хотите, чтобы нумерация перезапускалась всякий раз, когда изменяется атрибут QualifyingCode, вам следует использовать xsl:number
:
<xsl:number from="cd[@QualifyingCode!=preceding-sibling::cd[1]/@QualifyingCode]" level="any" />
Обратите внимание, что это не то же самое, что подсчет предыдущих родственных файлов с тем же квалификационным кодом; разница станет очевидной, если вы добавите другой компакт-диск с @QualifyingCode= 1 к вашему текущему списку.
Ответ №3:
Я внес два изменения в ваш xslt: первое заключается в том, что обычно лучше использовать шаблон, а не для каждого. Другой конкретно отвечает на ваш вопрос, подсчитывая братьев и сестер, которые имеют одинаковый QualifyingCode
:
<?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 style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
<th style="text-align:left">ID</th>
</tr>
<xsl:apply-templates select="catalog/cd"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="count(preceding-sibling::cd[@QualifyingCode =
current()/@QualifyingCode]) 1"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
Комментарии:
1. Ах, я вижу, что я слишком медленно редактировал этот ответ. Надеюсь, что это в любом случае полезно.