Проверьте, находится ли узел в пути узла с определенным атрибутом - PullRequest
1 голос
/ 23 декабря 2010

Какой самый быстрый способ определить, находится ли текущий узел в пути узла с определенным атрибутом, с учетом этой структуры XML:

<root>
<item>
    <item name="x">
        <item></item>
        <item name="y"></item>
        <item></item>
    </item>
    <item></item>
    <item></item>
</item>
<item>
    <item name="z"></item>
    <item></item>
</item>

У меня есть переменная xsltчтобы сказать мне, что является текущим активным узлом.

Я хочу выполнить некоторый код, если текущий узел находится в пути узла с @name x.

Так, что если активный узелэто элемент с @name y, который должен выполнить код, если текущий активный узел является элементом с @name z, он не должен.

Мое лучшее решение на данный момент:

ancestor-or-self::item[@name = 'x']

Но поскольку существует более 30 тыс. Узлов элементов, рендеринг которых занимает вечность, есть ли более быстрый путь?(XSLT / XPATH 2 не является опцией)

Ответы [ 2 ]

2 голосов
/ 23 декабря 2010

Лучший подход сильно зависит от всей трансформации.

Можно предположить, что сопоставление с образцом оптимизировано, поэтому:

<xsl:template match="item[@name='x']//*">

Кроме того, вы можете использовать режимы, такие как:

<xsl:template match="item[@name='x']">
    <xsl:apply-templates mode="descandants-in-path">
</xsl:template>

<xsl:template match="node()" mode="descandants-in-path">

Или параметр, подобный:

<xsl:template match="item[@name='x']">
    <xsl:apply-templates>
        <xsl:with-param name="pIsInPath" select="true()"/>
    </xsl:apply-templates>
</xsl:template>

<!-- Tunnel rule -->
<xsl:template match="*">
    <xsl:param name="pIsInPath"/>
    <xsl:apply-templates>
        <xsl:with-param name="pIsInPath" select="$pIsInPath"/>
    </xsl:apply-templates>
</xsl:template>
0 голосов
/ 23 декабря 2010

Чтобы добавить к хорошему ответу @Alejandro:

Во имя полноты в XSLT можно определить ключ :

<xsl:key name="kInSubtreebyId" 
         match="item[ancestor-or-self::item[@name='x']]"
         use="generate-id()"/>

А затем ссылаться на этот ключ следующим образом :

<xsl:if test="key('kInSubtreebyId', generate-id())">
 . . . . . . .
</xsl:if>

Теоретически, использование такого ключа может быть быстрее, чем другие методы, если тест для какого-либо конкретного узла выполняется (в среднем) более одного раза.

Однако для индексов может потребоваться много памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...