2012-07-16 50 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

相關問題