开发者

Testing for preceding-sibling and matching descendant using xsl:key

I have a problem that I believe I need to use grouping using xsl:key to solve, but I am at a loss as to the correct syntax. For the following XML, when I process each <a/> element I need to test to see if

  1. the element has a preceding-sibling <markerStart/> element and a descendant </markerEnd> element with the same id.

    • By "p开发者_StackOverflow中文版receding-sibling" I mean that there must not be an <a/> between the current element and the <markerStart/> , so the <a/> marked <!-- # 5 --> should return false, while the <a/> marked <!-- # 1 --> and the first <a/> following the element marked <!-- # 2a --> should return true.
    • By "descendant" I mean that there must not be an <a/> descendant before the <markerEnd/> , so the <a/> marked <!-- # 0 --> and the first <a/> following the element marked <!-- # 2b --> should return false.
  2. OR the element has a descendant <markerStart/> element and a descendant </markerEnd> element with the same id.

    • By "descendant" I mean that there must not be an <a/> descendant before the <markerEnd/>.

For the following XML, I would expect the nodes marked with <!-- # 1 -->, <!-- # 2a -->, and <!-- # 4 --> to return true.

<root>
    <a><!-- # 0 -->
        <b>
            <c>
                <markerStart id="a1"/>
                <a> <!-- # 1 -->
                    <b>
                        <c>
                        <markeEnd id="a1"/>
                        </c>
                    </b>
                </a>
                <markerStart id="a2"/><!-- # 2a -->
                <markerStart id="a3"/><!-- # 2b -->
                <a><!-- # 2 -->
                    <b>
                        <c>
                        <markeEnd id="a2"/>
                            <a><!-- # 3 -->
                                <b>
                                    <c>
                                        <markeEnd id="a3"/>
                                    </c>
                                </b>
                            </a>
                        </c>
                    </b>
                </a>
                <markerStart id="a5"/>
                <a><!-- # 4 -->
                    <markerStart id="a4"/>
                    <b>
                        <c>
                        <markeEnd id="a4"/>
                        </c>
                    </b>
                </a>
                <a><!-- # 5 -->
                    <b>
                        <c>
                        <markeEnd id="a5"/>
                        </c>
                    </b>
                </a>
            </c>
        </b>
    </a>
</root>

I need to used XSL 1.0 for this problem. Any help is more than appreciated.


This stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kMarkerStartByFollowingMarkeEnd"
             match="markerStart"
             use="generate-id(following::markeEnd[1])"/>
    <xsl:key name="kMarkeEndByAncestorA"
             match="markeEnd"
             use="generate-id(ancestor::a[1])"/>
    <xsl:template match="a[key('kMarkeEndByAncestorA',
                               generate-id()
                           )[1]/@id =
                           key('kMarkerStartByFollowingMarkeEnd',
                               generate-id(key('kMarkeEndByAncestorA',
                                               generate-id()
                                           )[1])
                           )/@id]">
        <xsl:copy-of select="comment()"/>
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

Output:

<!-- # 1 --><!-- # 2 --><!-- # 4 -->
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜