查找直至特定点的元素

时间:2019-01-10 22:03:46

标签: xml xslt xpath xslt-2.0

我有一个XPath问题。我需要针对<iframe>中包含的所有<part>进行测试的条件,而不是<iframe>中包含的任何<chapter>的测试条件。请注意,<chapter>中包含<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>中的任何 subjectIds.forEach(async id => { await connection .createQueryBuilder() .relation(Note, 'subjects') .of(note) .add(id); }); 时,我不确定如何完成此操作。

1 个答案:

答案 0 :(得分:1)

  

我需要选择<iframe>中包含的任何<part>,而不是<iframe>中包含的任何<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