Как выбрать из ключа какое поле не пустое
У меня есть XML-файл и XSLT преобразование ниже:
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet version="1.0" type="text/xml" href="pets.xsl" ?>
<pets>
<pet name="Jace" type="dog" />
<pet name="Babson" type="" />
<pet name="Oakley" type="cat" />
<pet name="Tabby" type="dog" />
</pets>
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:key name="pets-key" match="pet" use="type" />
<xsl:template match="/" >
<html>
<head><title></title></head>
<body>
<xsl:for-each select="key('pets-key', '' )" >
<xsl:value-of select="@name" />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Как я могу выбрать всех домашних животных, типы которых не пустые, используя функцию ключа?
1 ответ
Решение
Следует отметить два момента:
- В определении вашего ключа произошла ошибка. Вам нужно использовать use="@type", а не use="type"
Вам нужно установить разницу, чтобы выбрать всех питомцев, чей тип не пуст, и при этом использовать функцию key(). Общий рецепт для установки разницы в XPATH 1.0...
$ node-set1 [count (. | $ node-set2)! = count ($ node-set2)]
В общем, правильная, но неэффективная таблица стилей XSLT 1.0 для использования ключа () и перечисления всех питомцев с непустым типом...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="kPets" match="pet" use="@type" />
<xsl:template match="/" >
<html>
<head><title>Pets with a type</title></head>
<body>
<ul>
<xsl:for-each select="*/pet[count(. | key('kPets', '' )) != count(key('kPets', '' ))]" >
<li><xsl:value-of select="@name" /></li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Это дает вывод...
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Pets with a type</title>
</head>
<body>
<ul>
<li>Jace</li>
<li>Oakley</li>
<li>Tabby</li>
</ul>
</body>
</html>
Сказав это, вопрос не совсем подходит как хороший пример использования ключей. В реальной жизни, если бы вы хотели достичь этого результата, лучшее, более эффективное решение XSLT 1.0 было бы...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="kPets" match="pet" use="@type" />
<xsl:template match="/*" >
<html>
<head><title>Pets with a type</title></head>
<body>
<ul>
<xsl:apply-templates />
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="pet[@type != .]">
<li><xsl:value-of select="@name" /></li>
</xsl:template>
</xsl:stylesheet>