为什么这种比较只适用于整数类型id



我想知道[@id=current()/@id]语句是否只有在id为整数时才能工作,例如:

<elem id="1">
<elem id="1">

但如果我有:

<elem id="AAA">
<elem id="AAA">

它不起作用。

失败的XSL:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:fn="http://www.w3.org/2005/xpath-functions"
                xmlns:tn="http://"
                exclude-result-prefixes="xsl xs fn tn">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*" />
    <xsl:template match="@*|node()">
        <xsl:copy> 
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy> 
    </xsl:template>
 <xsl:template match="genre/*">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="
     book[@id=current()/@id][@action='extend']                             
         [not( preceding-sibling::book[@id=current()/@id][@action='borrow'])]" />
            <xsl:for-each-group
                select="book[@id=current()/@id][@action='borrow'] 
             |   
            book[@id=current()/@id][@action='extend']
                [preceding-sibling::book[@id=current()/@id][@action='borrow']]"
                group-starting-with="book[@action='borrow']">
                <xsl:for-each select="current-group()[1]">
                    <xsl:copy>   
                        <xsl:apply-templates select="@*" />
                        <xsl:call-template name="merge-books-deeply">    
                            <xsl:with-param name="books" select="current-group()" />
                            <xsl:with-param name="name-path" select="()" />
                        </xsl:call-template>
                    </xsl:copy>
                </xsl:for-each>     
            </xsl:for-each-group>
            <xsl:apply-templates select="                             
     node()[ not( self::book[@id=current()/@id][@action=('borrow','extend')])]" />
        </xsl:copy>
    </xsl:template>
    <xsl:function name="tn:children-on-path" as="element()*">
        <xsl:param name="base" as="element()*" />   
        <xsl:param name="path" as="xs:string*" />    
        <xsl:choose>
            <xsl:when test="fn:empty($base)">
                <xsl:sequence select="()" />
            </xsl:when>
            <xsl:when test="fn:empty($path)">
                <xsl:copy-of select="$base/*" />     
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="tn:children-on-path(
     $base/*[name()=$path[1]],         
     $path[position() ne 1])" /> 
            </xsl:otherwise>  
        </xsl:choose>
    </xsl:function>
    <xsl:template name="merge-books-deeply">
        <xsl:param name="books" as="element()*" />
        <xsl:param name="name-path" as="xs:string*" />
        <xsl:for-each-group
            select="tn:children-on-path($books,$name-path)"
            group-by="name()">                                             
            <xsl:for-each select="current-group()[last()]" >  
                <xsl:copy>
                    <xsl:apply-templates select="@*" />
                    <xsl:call-template name="merge-books-deeply"> 
                        <xsl:with-param name="books" select="$books" />
                        <xsl:with-param name="name-path" select="$name-path,name()" />
                    </xsl:call-template>
                    <xsl:apply-templates select="text()" />        
                </xsl:copy>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

输入它工作的样本:

<root> 
    <library id="L1">
        <genre id="a">
            <shelf1 id="1">                
                <book id="1" action="borrow">
                    <attributes>
                        <user>John</user>                    
                    </attributes>
                    <other1>y</other1>
                </book>  
                <book id="1" action="extend">
                    <attributes>
                        <user>Woo</user>           
                        <length>3</length>
                    </attributes>
                    <other2>y</other2>
                </book>  
                <book id="1" action="extend">
                    <attributes>
                        <length>2</length>
                        <condition>ok</condition>
                    </attributes>
                    <other3>y</other3>
                </book>
                <book id="2" action="extend">
                    <attributes>
                        <length>99</length>
                        <condition>not-ok</condition>
                    </attributes>
                    <other>y</other>
                </book>
            </shelf1>
            <shelf1 id="b">...
            </shelf1>
        </genre>
        <genre id="b">...
        </genre>
    </library>
</root>

如果我将书的id更改为1a:

<root> 
    <library id="L1">
        <genre id="a">
            <shelf1 id="1">                
                <book id="1a" action="borrow">
                    <attributes>
                        <user>John</user>                    
                    </attributes>
                    <other1>y</other1>
                </book>  
                <book id="1a" action="extend">
                    <attributes>
                        <user>Woo</user>           
                        <length>3</length>
                    </attributes>
                    <other2>y</other2>
                </book>  
                <book id="1a" action="extend">
                    <attributes>
                        <length>2</length>
                        <condition>ok</condition>
                    </attributes>
                    <other3>y</other3>
                </book>
                <book id="2" action="extend">
                    <attributes>
                        <length>99</length>
                        <condition>not-ok</condition>
                    </attributes>
                    <other>y</other>
                </book>
            </shelf1>
            <shelf1 id="b">...
            </shelf1>
        </genre>
        <genre id="b">...
        </genre>
    </library>
</root>

我的错误输出:(它根本不合并)

<root> 
    <library id="L1">
        <genre id="a">
            <shelf1 id="1">                
                <book id="a1" action="borrow">
                    <attributes>
                        <user>John</user>                    
                    </attributes>
                    <other1>y</other1>
                </book>  
                <book id="a1" action="extend">
                    <attributes>
                        <user>Woo</user>           
                        <length>3</length>
                    </attributes>
                    <other2>y</other2>
                </book>  
                <book id="a1" action="extend">
                    <attributes>
                        <length>2</length>
                        <condition>ok</condition>
                    </attributes>
                    <other3>y</other3>
                </book>
                <book id="2" action="extend">
                    <attributes>
                        <length>99</length>
                        <condition>not-ok</condition>
                    </attributes>
                    <other>y</other>
                </book>
            </shelf1>
            <shelf1 id="b">...
            </shelf1>
        </genre>
        <genre id="b">...
        </genre>
    </library>
</root>

预期输出:

<root> 
    <library id="L1">
        <genre id="a">
            <shelf1 id="1">                
                <book id="1a" action="borrow">
                    <attributes>
                        <user>Woo</user>           
                        <length>2</length>
                        <condition>ok</condition>                  
                    </attributes>
                    <other1>y</other1>
                </book>  
                <book id="2" action="extend">
                    <attributes>
                        <length>99</length>
                        <condition>not-ok</condition>
                    </attributes>
                    <other>y</other>
                </book>
            </shelf1>
            <shelf1 id="b">...
            </shelf1>
        </genre>
        <genre id="b">...
        </genre>
    </library>
</root>

对于每个具有操作=借用的节点,然后是一个或多个具有操作=扩展的节点

  • 使用action=borrow将其合并到节点中。

  • 将属性子项合并在一起,使其具有兄弟项中具有最新值的所有唯一属性。

  • 保持其他孩子的不变

合并只发生在具有相同id的节点上。

谢谢。当做John

也许您遇到了上下文问题。比较应该有效。下面是一个例子。。。

XML输入

<tests>
    <test>
        <elem id="1"/>
        <elem id="1"/>
    </test>
    <test>
        <elem id="AAA"/>
        <elem id="AAA"/>
    </test>
    <test>
        <elem id="BBB"/>
        <elem id="CCC"/>
    </test>
    <test>
        <elem id="2"/>
        <elem id="3"/>
    </test>
</tests>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>
    <xsl:template match="elem[1]">
        <xsl:text>Comparing id </xsl:text>
        <xsl:value-of select="concat('&quot;',@id,'&quot;&#xA;')"/>
        <xsl:value-of select="concat('&#x9;',
            boolean(following-sibling::*[@id=current()/@id]),
            '&#xA;')"/>
    </xsl:template>
</xsl:stylesheet>

输出

Comparing id "1"
    true
Comparing id "AAA"
    true
Comparing id "BBB"
    false
Comparing id "2"
    false

编辑

在看了你更新的例子之后,它看起来肯定像是一个上下文问题。看看模板的开头:

<xsl:template match="genre/*">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="
     book[@id=current()/@id][@action='extend']                             
         [not( preceding-sibling::book[@id=current()/@id][@action='borrow'])]" />

请注意,匹配项为genre/*;这就是目前的情况。根据您的输入,这将是shelf1。然后,第二CCD_ 5的选择从CCD_ 6开始。对我来说,如果它的id属性等于shelf1id属性,那么它看起来就像是在选择book。为了测试这一点,您还可以将shelf1id更改为1a,这可能会起作用。(这就是第一个例子有效的原因;shelf1book中的id匹配

我现在无法检验这个理论,但我认为这就是为什么这种比较似乎不起作用的原因。(这是有效的,你只是没有比较你认为你在比较的东西。)

字符串比较不需要显式的字符串转换。换句话说,它应该像你写的那样工作
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="elem">
    <xsl:if test="count(../elem[@id=current()/@id]) &gt; 1">
      <xsl:value-of select="@id"/>: has dup
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

应用于此输入时:

<r>
    <elem id="AAA">one</elem>
    <elem id="AAA">two</elem>
    <elem id="ZZZ">three</elem>
</r>

产生以下输出:

AAA: has dup
AAA: has dup

来自XPath规范:

否则,如果至少有一个要比较的对象是数字,则每个要比较的对象都被转换为一个数字,就好像通过应用数字函数。否则,要比较的两个对象都是通过应用字符串函数转换为字符串。

最新更新