Тестирование предшествующего брата и соответствующего потомка с использованием xsl: key - PullRequest
2 голосов
/ 11 марта 2011

У меня есть проблема, которую я считаю, что мне нужно использовать группировку, используя xsl: key для решения, но я не знаю, каков правильный синтаксис. Для следующего XML, когда я обрабатываю каждый элемент <a/>, мне нужно проверить, есть ли

  1. элемент имеет предшествующий элемент <markerStart/> и дочерний элемент </markerEnd> с тем же идентификатором.

    • Под «предшествующим братом» я подразумеваю, что между текущим элементом и <markerStart/> не должно быть <a/>, поэтому <a/>, помеченный <!-- # 5 -->, должен возвращать false, тогда как <a/>, помеченный <!-- # 1 --> и первый <a/> после элемента, помеченного <!-- # 2a -->, должен вернуть true.
    • Под «потомком» я подразумеваю, что не должно быть <a/> потомка до <markerEnd/>, поэтому <a/>, помеченный <!-- # 0 -->, и первый <a/>, следующий за элементом, помеченным <!-- # 2b -->, должны возвращать false .
  2. ИЛИ элемент имеет элемент-потомок <markerStart/> и элемент-потомок </markerEnd> с таким же идентификатором.

    • Под "потомком" я подразумеваю, что не должно быть <a/> потомка до <markerEnd/>.

Для следующего XML я бы ожидал, что узлы, отмеченные <!-- # 1 -->, <!-- # 2a --> и <!-- # 4 -->, вернут 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>

Мне нужно использовать XSL 1.0 для этой проблемы. Любая помощь приветствуется.

1 Ответ

1 голос
/ 11 марта 2011

Эта таблица стилей:

<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>

Вывод:

<!-- # 1 --><!-- # 2 --><!-- # 4 -->
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...