внимание на ось в предыдущем примере — preceding-sibling. До сих пор мы видели только оси, выбиравшие образцы XSLT — оси child и attribute; теперь же мы рассмотрим новые оси, возможные в полных выражениях XPath, и начнем с оси ancestor.
Применение оси ancestor
Ось ancestor (предок) содержит всех предков контекстного узла, включая родителей, дедушек, прадедушек и т.д. Эта ось всегда содержит корневой узел — если только контекстным узлом не является сам корневой узел.
Взгляните на листинг 7.3, в котором при помощи оси ancestor осуществляется поиск имен (хранимых в элементе <NAME>) всех предков элементов <MASS>.
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:template match='MASS'>
<xsl:for-each select='ancestor::*'>
<xsl:value-of select='./NAME'/>
</xsl:for-each>
</xsl:template>
<xsl:template match='PLANET'>
<xsl:apply-templates select='MASS'/>
</xsl:template>
</xsl:stylesheet>
Вот результат применения этой таблицы стилей к planets.xml:
<?xml version='1.0' encoding='utf-8'?>
Mercury
Venus
Earth
Применение оси ancestor-or-self
Ось ancestor-or-self содержит всех предков контекстного узла, а также сам контекстный узел. Это означает, помимо прочего, что такая ось всегда содержит корневой узел.
В листинге 7.4 добавлены атрибуты AUTHOR со значением «Steve» в весь документ.
<?xml version=1.0'?>
<?xml-stylesheet type='text/xml' href='planets.xsl'?>
<PLANETS AUTHOR='Steve' >
<PLANET AUTHOR='Steve' >
<NAME>Mercury</NAME>
<MASS AUTHOR='Steve' UNITS='(Earth = 1)'>.0553</MASS>
<DAY UNITS='days'>58.65</DAY>
<RADIUS UNITS='miles'>1516</RADIUS>
<DENSITY UNITS='(Earth = 1)'>.983</DENSITY>
<DISTANCE UNITS='million miles'>43.4</DISTANCE><!--B перигелии-- >
</PLANET>
<PLANET AUTHOR='Steve'>
<NAME>Venus</NAME>
<MASS UNITS='(Earth = 1)'>.815</MASS>
<DAY UNITS='days'>116.75</DAY>
<RADIUS UNITS='miles'>3716</RADIUS>
<DENSITY UNITS='(Earth = 1)'>.943</DENSITY>
<DISTANCE UNITS='million miles'>66.8</DISTANCE><!--В перигелии-- >
</PLANET>
<PLANET>
<NAME>Earth</NAME>
<MASS UNITS='(Earth = 1)'>1</MASS>
<DAY UNITS='days'>1</DAY>
<RADIUS UNITS='miles'>2107</RADIUS>
<DENSITY UNITS='(Earth = 1)'>1</DENSITY>
<DISTANCE UNITS='million miles'>128.4</DISTANCE><!--B перигелии-- >
</PLANET>
</PLANETS>
Предположим теперь, что я хочу перечислить по имени всех предков элементов <MASS>, имеющих атрибут AUTHOR, а также текущий элемент <MASS>, если у него есть атрибут AUTHOR. Это можно сделать при помощи оси ancestor-or-self и функции local-name (листинг 7.5).
<?xml version='1.0'?>
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='xml'/>
<xsl:template match='MASS'>
<xsl:for-each select='ancestor-or-self::*[@AUTHOR]'>
<xsl:value-of select='local-name(.)'/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match='PLANET'>
<xsl:apply-templates select='MASS'/>
</xsl:template>
</xsl:stylesheet>
Вот результат; показаны выбранные предки всех трех элементов <MASS>, включая сам элемент <MASS>, при условии, что у него имеется атрибут AUTHOR:
