Xslt xPath奇怪之处在于谓词在某种程度上是必需的

Xslt xPath奇怪之处在于谓词在某种程度上是必需的,xslt,xpath,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]/nod

这似乎是一个奇怪的问题,因为我确实找到了一个可行的解决方案,但有人能告诉我为什么我下面的第一个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>

文学

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

child::x[position()=2]

child::*[name()='x' and position()=2]
这两种结构的含义完全不同。第一个表达式考虑名称为“x”的所有子元素,然后返回其中的第二个。第二个构造考虑所有子元素,然后选择第二个子元素,前提是其名称为“x”


当然,这些“有效”取决于您的需求。它们都是正确的,只是做了不同的事情。

我猜您的
enes
前缀绑定到了不同的uri,但是如果没有输入XML和XSLT(至少是显示名称空间声明的部分),就无法分辨。我的XML看起来是这样的:带有属性xmlns=“enes”出现在每个节节点中。当我移除它时,更简单的解决方案起作用了。谢谢,丹尼尔。@kalinma,你能帮我把输入文件编辑成你的问题吗?另外,只有添加一个完整的XSLT样式表,人们可以用它来重现您的问题,您的问题才是真正完整的。我同意Mathias的观点,如果您添加XSLT,我们可以确切地告诉您问题出在哪里。在我看来,从输入XML中删除命名空间不应该被认为是一个答案。奇怪的是,即使使用NAME()代替Loal-NAMEL(),这也是可行的:虽然我不知道这个问题是用XSLT解析器来解决的。为什么你觉得奇怪的是,这两个表达式会产生不同的结果?我想我已经解释了为什么这是你应该期待的。