xPath奇怪,其中谓词是某种必要的

时间:2015-12-15 18:35:01

标签: xslt xpath

这可能看起来像一个奇怪的问题,因为我确实找到了一个有效的解决方案,但是有人可以告诉我为什么我的第一个xPath工作正常而第二个不工作?我确实在我的XSLT中包含了enes名称空间。

解决方案A有效:

<xsl:copy-of select="document('my_document_of_citations.xml')//node()[namespace-uri()='enes' and local-name()='section' and position() = $section-pos]/node()[namespace-uri()='enes' and local-name()='litref']" />

解决方案B不起作用:

<xsl:copy-of select="document('my_document_of_citations.xml')//enes:section[position() = $section-pos]/enes:litref" />

这是样式表,只有非germain模板中的代码和函数被省略:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="enes thieme xhtml xlink xs" version="2.0" xmlns:enes="http://www.thieme.de/enes" xmlns:thieme="http://www.thieme.de/enes" xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="enesfunc">
<xsl:output method="xml" indent="yes" version="1.1" omit-xml-declaration="no" encoding="UTF-8" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <xsl:apply-templates />
</xsl:template>

<!-- Identity Transform -->
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="part[@type eq 'content']/section[@level eq '1']">
    <xsl:element name="section" xmlns="enes">
        <xsl:attribute name="level" select="1" />
        <xsl:attribute name="id"><xsl:value-of select="./@id"/></xsl:attribute>
        <xsl:attribute name="counter"><xsl:value-of select="./@counter"/></xsl:attribute>
        <xsl:apply-templates />
        <!-- Insert a level 2 section with the references for this level 1 section from references_by_chapter.xml here. -->
        <xsl:element name="section" xmlns="enes">
            <xsl:attribute name="level" select="2" />
            <xsl:attribute name="type">
                <xsl:text>literature</xsl:text>
            </xsl:attribute>

            <!-- Get the absolute position of this section within the document. -->
            <xsl:variable name="section-pos" select="count(./preceding-sibling::section) + count(ancestor::node()/preceding-sibling::node()[local-name() eq 'part']/node()[local-name() eq 'section']) + 1" />

            <!-- Copy extracted references from xml here -->
            <xsl:copy-of select="document('references_by_chapter.xml')//node()[namespace-uri()='enes' and local-name()='section' and position() = $section-pos]/node()[namespace-uri()='enes' and local-name()='litref']" />
            <!-- <xsl:copy-of select="document('references_by_chapter.xml')//enes:section[position() = $section-pos]/enes:litref" /> -->
        </xsl:element>
    </xsl:element>
</xsl:template>

<xsl:template match="section[@level eq '2']//text()">
    <!-- code to transform level 2 sections here. -->
</xsl:template>

<xsl:function name="func:myStrFunc">
    <!-- more code here. -->
</xsl:function>

1 个答案:

答案 0 :(得分:1)

简化代码以删除不相关的细节,请考虑

child::x[position()=2]

child::*[name()='x' and position()=2]

这两种结构的含义完全不同。第一个表达式考虑名称为“x”的所有子元素,然后返回第二个表达式。第二个构造考虑所有子元素,然后选择第二个子元素,前提是它的名称为“x”。

其中哪些“有效”当然取决于您的要求。它们都是正确的,它们只做不同的事情。