Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 使用时的结构要求;除「;在XPATH/XSL中_Xslt_Xpath_Xslt 2.0_Xpath 2.0_Except - Fatal编程技术网

Xslt 使用时的结构要求;除「;在XPATH/XSL中

Xslt 使用时的结构要求;除「;在XPATH/XSL中,xslt,xpath,xslt-2.0,xpath-2.0,except,Xslt,Xpath,Xslt 2.0,Xpath 2.0,Except,在xpath中使用“except”时遇到问题。下面是一段问题代码。(我试图在不掩盖整个问题的情况下尽可能简化。) ... 当您创建xsl:variable而不使用@select并且不将@指定为类型时,它会将变量创建为一个变量 您希望创建一系列节点,以便在操作符中对它们进行比较时,“看到”它们是相同的节点。您可以通过为xsl:variable指定as=“node()*”,并使用xsl:sequence而不是xsl:copy of: <xsl:variable name="badValues

在xpath中使用“except”时遇到问题。下面是一段问题代码。(我试图在不掩盖整个问题的情况下尽可能简化。)


...

当您创建
xsl:variable
而不使用
@select
并且不将
@指定为类型时,它会将变量创建为一个变量

您希望创建一系列节点,以便在操作符中对它们进行比较时,“看到”它们是相同的节点。您可以通过为
xsl:variable
指定
as=“node()*”
,并使用
xsl:sequence
而不是
xsl:copy of

<xsl:variable name="badValues" as="node()*">
    <xsl:for-each select="$root/A[not(VALUE)]">
        <xsl:choose>
            <xsl:when test="count($root/A[DOMAIN=current()/DOMAIN 
                                   and VARIABLE=current()/VARIABLE])=1">
                <xsl:sequence select="."/>
            </xsl:when>
        </xsl:choose>
    </xsl:for-each>
</xsl:variable>
然后将您的值更改为:

<xsl:variable name="badValues" 
     select="$root/A[not(VALUE)]
                    [count(key('by-dom-and-var', 
                               concat(DOMAIN, '|', VARIABLE))/VARIABLE) = 1]"/>>
针对此XML文件执行:

<doc>
    <A>
        <VALUE>skip me</VALUE>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
    <A>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
    <A>
        <DOMAIN>b</DOMAIN>
        <VARIABLE>b</VARIABLE>
    </A>
    <A>
        <DOMAIN>c</DOMAIN>
        <VARIABLE>c</VARIABLE>
    </A>
    <A>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
</doc>

跳过我
A.
A.
A.
A.
B
B
C
C
A.
A.
它产生以下输出:

<rootA>d1e3, d1e15, d1e24, d1e33, d1e42</rootA>
<originalBadValues>d2e1, d2e9</originalBadValues>
<badValues>d1e24, d1e33</badValues>
<final>d1e3, d1e15, d1e42</final>
d1e3、d1e15、d1e24、d1e33、d1e42
d2e1,d2e9
d1e24,d1e33
d1e3、d1e15、d1e42

关于新创建节点的临时树的良好解释。不过,对于解决方案,我建议通过定义一个键
,然后简单地执行
,来简化代码。这一点很好。我在答案中添加了一个解释,即如果使用
@select
,变量也会被创建为一个序列。首先,我想指出,
..
必须更改为
..
,我只想让其他可能看到这一点的人明白这一点。非常感谢你们的回答和建议。这些不仅解决了我的问题,而且还简化了我的其他代码,使我的生活更轻松。我一直在试图找到一种不用循环在xsl中进行“连接”的方法,看起来使用键可以解决这个问题。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:template match="/">
    <xsl:variable name="root" select="*" as="item()*"/>       
    <xsl:variable name="originalBadValues">
        <xsl:for-each select="$root/A[not(VALUE)]">
            <xsl:choose>
                <xsl:when test="count($root/A[DOMAIN=current()/DOMAIN 
                                      and VARIABLE=current()/VARIABLE])=1">
                    <xsl:copy-of select="."/>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="badValues" as="node()*">
        <xsl:for-each select="$root/A[not(VALUE)]">
            <xsl:choose>
                <xsl:when test="count($root/A[DOMAIN=current()/DOMAIN 
                                      and VARIABLE=current()/VARIABLE])=1">
                    <xsl:sequence select="."/>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </xsl:variable>

        <!--These are the generated ID values of all the A elements-->
        <rootA>
            <xsl:value-of select="$root/A/generate-id()" 
                          separator=", "/>
        </rootA>
        <!--These are the generated ID values for 
            the original $badValues/A --> 
        <originalBadValues>
            <xsl:value-of select="$originalBadValues/A/generate-id()" 
                          separator=", " />
        </originalBadValues>
        <!--These are the generated ID values for 
            the correct selection of $badValues-->
        <badValues>
            <xsl:value-of select="$badValues/generate-id()" 
                          separator=", " />
        </badValues>
        <!--The generated ID values for the result of 
            the except operator filter-->
        <final>
            <xsl:value-of select="($root/A except $badValues)/generate-id()" 
                          separator=", "/>
        </final>
    </xsl:template>        
</xsl:stylesheet>
<doc>
    <A>
        <VALUE>skip me</VALUE>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
    <A>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
    <A>
        <DOMAIN>b</DOMAIN>
        <VARIABLE>b</VARIABLE>
    </A>
    <A>
        <DOMAIN>c</DOMAIN>
        <VARIABLE>c</VARIABLE>
    </A>
    <A>
        <DOMAIN>a</DOMAIN>
        <VARIABLE>a</VARIABLE>
    </A>
</doc>
<rootA>d1e3, d1e15, d1e24, d1e33, d1e42</rootA>
<originalBadValues>d2e1, d2e9</originalBadValues>
<badValues>d1e24, d1e33</badValues>
<final>d1e3, d1e15, d1e42</final>