Найти элементы до определенной точки - PullRequest
0 голосов
/ 11 января 2019

У меня проблема с XPath. Мне нужно условие теста для любых <iframe>, включенных в <part>, но не для всех <iframe>, включенных в <chapter>. Обратите внимание, что <chapter> s включены в <part>.

XML:

<book>
<part id="p1">
    <h1>Add a heading</h1>
    <p>some text here</p>
    <p>more text here</p>
    <div>
        <h2>Add another heading</h2>
        <p>more text</p>
    </div>
    <div class="someDivision">
        <div class="someOtherDivision">
            <h2>Heading</h2>
            <div class="sect">
                <h2>Heading</h2>
                <iframe>Add iframe content</iframe>
            </div>
        </div>
    </div>
    <chapter>
        <h1>Add a chapter heading</h1>
        <p>some chapter text here</p>
        <div class="someDivision">
            <div class="someOtherDivision">
                <h2>Heading</h2>
                <div class="sect">
                    <h2>Heading</h2>
                    <iframe>Add more iframe content</iframe>
                </div>
            </div>
        </div>  
    </chapter>
</part>
<part id="p2">
    <h1>Add a heading</h1>
    <p>some text here</p>
    <p>more text here</p>
    <div>
        <h2>Add another heading</h2>
        <p>more text</p>
    </div>
    <chapter>
        <h1>Add a chapter heading</h1>
        <p>some chapter text here</p>
        <div class="someDivision">
            <div class="someOtherDivision">
                <h2>Heading</h2>
                <div class="sect">
                    <h2>Heading</h2>
                    <iframe>Add more iframe content</iframe>
                </div>
            </div>
        </div>  
    </chapter>
</part>
</book>

XSLT:

<xsl:template match="/">
        <xsl:element name="manifest">
            <xsl:for-each select="//part">
                <xsl:element name="item">
                    <xsl:attribute name="id" select="@id/string()"/>
                    <xsl:if test="//div[@class='someDivision']/div[@class='someOtherDivision']//iframe">
                        <xsl:attribute name="properties" select="'remote-resources'"/>
                    </xsl:if>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

Я получаю этот результат:

<manifest>
    <item id="p1" properties="remote-resources"/>
    <item id="p2" properties="remote-resources"/>
</manifest>

Но я хочу только:

<manifest>
    <item id="p1" properties="remote-resources"/>
</manifest>

Поскольку нет <iframe> непосредственно в <part> и не вложено в <chapter>. Но я не уверен, как это сделать, когда мой XPath выберет любой <iframe> в пределах <part> (включая те, что в <chapter>.

1 Ответ

0 голосов
/ 11 января 2019

Мне нужно выбрать любой <iframe>, который включен в <part>, но не любые <iframe> s, которые включены в <chapter>.

Как насчет:

/book/part//iframe[not(ancestor::chapter)]

Добавлено:

Если вы хотите протестировать из контекста part, если текущий part содержит какие-либо iframe элементы, которые не являются потомками chapter, то выполните что-то вроде этого:

<xsl:template match="/book">
    <manifest>
        <xsl:for-each select="part">
            <item id="{@id}">
                <xsl:if test=".//iframe[not(ancestor::chapter)]">
                    <!-- code if true -->
                </xsl:if>
            </item>
        </xsl:for-each>
    </manifest>
</xsl:template>

Демо : http://xsltransform.hikmatu.com/jyH9rLY

...