- PR -

XSLTで処理を任意の場所で止めたい

1
投稿者投稿内容
deu
会議室デビュー日: 2003/01/31
投稿数: 6
投稿日時: 2003-01-31 15:47
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<dd>
<aa>
<cc/>
</aa>
</dd>
<dd>
<bb>
<cc/>
</bb>
</dd>
<bb>
<aa/>
</bb>
<aa/>
</root>

このようなxmlがあって、aa要素を許さない場合に、aa要素を検出するxsltがあるとします。
(簡略化しておりますので書き方が怪しいのはご勘弁ください)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no" omit-xml-declaration="no"/>

<xsl:template match="*">
<xsl:param name="stop"/>
<xsl:if test="not($stop='true')">
<xsl:call-template name="parse"/>
</xsl:if>
</xsl:template>

<xsl:template name="parse">
<xsl:choose>
<xsl:when test="self::aa">aa要素が現われました。
<xsl:apply-templates><xsl:with-param name="stop">true</xsl:with-param></xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

希望としては、aa要素ひとつにぶつかる度に検証作業を中断したいのですが、
どうしてもうまくいきません。

たとえば、ルート直下に子要素が3つあるとします。
その、一つ目の子要素の子孫にaaがあった場合、そのaaを検出します。
そして、その子孫についてはそこで検証が泊まるのです。
しかし。二つ目の子要素、3つ目の子要素に関しては検証を続けてしまうので、

aa要素が現われました。
aa要素が現われました。
aa要素が現われました。

と何回も出てきてしまいます。

そこで、以下のように書いてみましたがこれもダメでした。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="text" indent="no" omit-xml-declaration="no"/>

<xsl:template match="root">
<xsl:call-template name="for">
<xsl:with-param name="nodeCount" select="1"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="for">
<xsl:param name="nodeCount"/>
<xsl:variable name="lastCount" select="count(/root/*)"/>
<xsl:if test="$lastCount &gt;= $nodeCount">
<xsl:apply-templates select="*[$nodeCount]" mode="for"/>
<xsl:call-template name="for">
<xsl:with-param name="nodeCount">
<xsl:value-of select="$nodeCount +1" />
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template match="*" mode="for">
<xsl:choose>
<xsl:when test="self::aa">aa要素が現われました。
<xsl:apply-templates><xsl:with-param name="stop">true</xsl:with-param></xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates mode="for"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

どなたかアドバイスをいただけませんでしょうか?
よろしくお願いいたします。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2003-02-04 00:23
そもそも、パターンマッチ駆動の言語は止められないのでは?
大域脱出とかも無さそうですし。
xsl:apply-templates select="//aa[1]"
程度で済ませられません?
しかし、木を全部作るのは無駄かも。
1

スキルアップ/キャリアアップ(JOB@IT)