-2

[@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 が指定されたすべてのノードの後に​​、action=extend が指定された 1 つ以上のノードが続く場合

  • action=borrow でノードにマージします。

  • 属性の子をマージして、兄弟からのすべての一意の属性が最新の値を持つようにします。

  • 他の子は変更しないでください

マージは、同じ ID を持つノードでのみ発生します。

ありがとう。よろしく、ジョン

4

2 に答える 2

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。次に、2番目の選択が でxsl:apply-templates始まりbook[@id=current()/@id]ます。私には、これは の属性と等しい属性を持っbookているかどうかを選択しているように見えます。これをテストするには、ofを に変更することもできます。おそらく動作するでしょう。(それが最初の例が機能する理由です; ofとmatch.ididshelf1idshelf11aidshelf1book

この理論を今すぐテストすることはできませんが、それが比較が機能していないように見える理由だと思います. (それは機能しています。比較していると思うものを比較していないだけです。)

于 2012-07-16T18:32:19.100 に答える
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

XPath仕様から:

それ以外の場合、比較するオブジェクトの少なくとも 1 つが数値の場合、数値関数を適用したかのように、比較する各オブジェクトが数値に変換されます。それ以外の場合、比較対象の両方のオブジェクトは、string 関数を適用したかのように文字列に変換されます。

于 2012-07-16T18:26:10.063 に答える