Xpoint
   [напомнить пароль]

xsl или xpath перечисление родителей эелемента

Метки: [без меток]
2007-06-25 12:30:15 [обр] Александр Костюков[досье]

Допустим у меня есть нумерованный список.
# cars

  • opel
  • Mini

          - s
          - One

  • BMW

Как мне через xsl или xpath прописать для элемента путь который состоит из перечисленный родителей этого элемента.
Например, для элемента "One" путь должен быть "cars/Mini/One".

С веткой ancestor-or-self как-то не удается получить нужный результат.

Подскажите как конкретно получить строку "cars/Mini/One".

спустя 1 час 36 минут [обр] GRAy(64/259)[досье]

Ну допустим так:

<?xml version="1.0" encoding="windows-1251" ?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="windows-1251" indent="yes" />
<xsl:template match="/">
  <xsl:apply-templates select="//One" mode="out"/>
</xsl:template>
<xsl:template match="*" mode="out" >
  <xsl:variable name="path">
    <xsl:apply-templates select="." mode="getpath"/>
  </xsl:variable>
  <path><xsl:value-of select="$path" /></path>
</xsl:template>
<xsl:template match="*" mode="getpath">
  <xsl:for-each select="ancestor-or-self::*">/<xsl:value-of select="name(.)" />[position()=<xsl:value-of select="position()"/>]</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Учтите, что путь типа "/cars/Mini/One" не является указателем на уникальный элемент в xml дереве, поэтому я добавил ещё проверку на position().

спустя 27 минут [обр] GRAy(64/259)[досье]
Забыл совсем. Такой способ определения элемента не подходит т.к. он отталкивается от его позиции в текущем списке полученном из ancestor-or-self а не его позиции в родителе. Получить "правильную" достаточно нетривиально:
<?xml version="1.0" encoding="windows-1251" ?>
<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="windows-1251" indent="yes" />
<xsl:template match="/">
  <xsl:apply-templates select="//link" mode="out"/>
</xsl:template>
<xsl:template match="*" mode="out" >
  <xsl:variable name="path">
    <xsl:apply-templates select="." mode="getpath"/>
  </xsl:variable>
  <path><xsl:value-of select="$path" /></path>
</xsl:template>
<xsl:template match="*" mode="getpath">
  <xsl:for-each select="ancestor-or-self::*">/<xsl:value-of select="name(.)" />[position()=<xsl:apply-templates select="." mode="getposition"/>]</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="getposition">
  <xsl:variable name="curnodeid" select="generate-id(current())" />
  <xsl:for-each select="../*[name() = name(current())]"><xsl:if test="generate-id(.)=$curnodeid"><xsl:value-of select="position()"  /></xsl:if></xsl:for-each>
</xsl:template>
</xsl:stylesheet>
спустя 2 часа 20 минут [обр] Александр Костюков[досье]
Большое спасибо, буду разбираться.
Powered by POEM™ Engine Copyright © 2002-2005