2012-07-16 75 views
-2

我想知道做了发言[@id=current()/@id]如果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> 

对于动作的每一个节点=借随后用动作的一个或多个节点=延伸

  • 合并一起与操作的节点=借。

  • 将子属性合并为一个子属性,使它具有来自具有最新值的兄弟的所有唯一属性。

  • 保持不变的

其他孩子合并只能与具有相同ID的节点发生。

谢谢。 Regards, John

+2

它应该工作,你有什么证据证明它不是? – 2012-07-16 22:17:01

+0

@MichaelKay请看看添加的例子,我是否缺少(非常感谢) – John 2012-07-17 00:39:01

+4

@John,缺少的是(a)描述了结果是什么,(b)描述了你期望得到的结果。“不起作用”太模糊了。此外,如果您的示例数据可用,它将有所帮助; as它是,它不是一个格式良好的XML文档。) – LarsH 2012-07-17 02:01:19

回答

1

字符串比较不需要显式字符串转换。换句话说,它应该像你写的那样工作。下面是一个例子:

<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 

the XPath spec

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

3

也许您正在发生上下文问题。比较应该工作。下面是一个例子...

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。然后第二个xsl:apply-templates的选择以book[@id=current()/@id]开始。对我来说,这看起来像是选择了book,前提是它的id属性等于属性shelf1。要测试这个,你也可以将的shelf1更改为1a,它可能会工作。 (这是第一个例子工程的原因;的shelf1idbook比赛

我现在无法验证这一理论,但我认为这就是它看起来比较不工作的原因(这)

+0

请看看添加的例子,我错过了什么吗?上下文问题意味着什么?非常感谢。 – John 2012-07-17 00:39:55

+2

@John - 像Dimitre在评论中说的,请添加一个完整的例子。这包括一个XML示例,它将在您的示例XSLT应用时重现问题。 – 2012-07-17 02:43:58

+0

请看我添加的例子,并告诉我我错过了什么。非常感谢 – John 2012-07-17 19:19:28

相关问题