Xml 在带有前缀的输入元素的XPath表达式中使用变量

Xml 在带有前缀的输入元素的XPath表达式中使用变量,xml,variables,xslt,xpath,Xml,Variables,Xslt,Xpath,我有3份员工记录如下。在我的XSLT中,我创建了一个行号为1、2和3的变量,然后通过每一行循环打印fname。但它不起作用 以下是输入xml: <tns:empLines> <tns:empLine> <can:fname>John</can:fname> <can:lname>Doe</can:lname> <can:age>20</can:age&

我有3份员工记录如下。在我的XSLT中,我创建了一个行号为1、2和3的变量,然后通过每一行循环打印fname。但它不起作用

以下是输入xml:

<tns:empLines>
    <tns:empLine>
        <can:fname>John</can:fname>
        <can:lname>Doe</can:lname>
        <can:age>20</can:age>
        <can:lineNumber>1</can:lineNumber>
    </tns:empLine>
    <tns:empLine>
        <can:fname>James</can:fname>
        <can:lname>Douglas</can:lname>
        <can:age>24</can:age>
        <can:lineNumber>2</can:lineNumber>
    </tns:empLine>
    <tns:empLine>
        <can:fname>Joe</can:fname>
        <can:lname>Sims</can:lname>
        <can:age>30</can:age>
        <can:lineNumber>3</can:lineNumber>
    </tns:empLine>
</tns:empLines>
下面是我的xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:template match="/">
        <xsl:variable name="lines">
            <line num="1"/>
            <line num="2"/>
            <line num="3"/>
        </xsl:variable>
        <root>
            <xsl:for-each select="$lines/line">
                <pc>
                    <xsl:value-of select="//*[local-name()='empLines']/*[local-name()='empLine'][*[local-name()='lineNumber']=current()/@num]/*[local-name()='fname']/text()"/>
                </pc>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>
在XSLT1.0中,您显示的lines变量包含一个结果树片段而不是节点集,因此它不能在XPath中的/之前使用,就像在$lines/line中一样。有几种方法可以解决这个问题

使用XSLT2.0。 使用非通用可移植的节点集扩展函数将$行转换为节点集。 将$line的内容作为样式表中的顶级元素,如下所示: -

请注意,顶级元素必须位于xsl以外的命名空间中


但是,michael说得很对,您显示的XML输入在名称空间方面的格式不好。这应该会给你一个错误。

它不工作意味着什么?您是否收到错误消息或垃圾打印?1。这不能是您的输入:必须声明前缀并将其绑定到命名空间。2.您不能在以这种方式定义的变量上循环,因为它不是节点集。我不知道为什么你不能在雇员身上绕圈子:你想在这里取得什么样的结果?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:foo="foo">

  <foo:lines>
    <line num="1"/>
    <line num="2"/>
    <line num="3"/>
  </foo:lines>

  <xsl:template match="/">
    <xsl:variable name="lines" select="document('')/foo:lines" />
    <root>
      <xsl:for-each select="$lines/line"> ...