2011-08-02 9 views
0

ソートの実装に問題があります。特定の要素を並べ替える以外は、1対1のコピーを実行するXML文書があります。スキーマに対して検証するためには、コピーの後に文書の構造が同じでなければなりません。私はスキーマを制御できないので、それを変更することはできません。私は特定の順序に<item>の要素をソートしたいソートされた要素に兄弟がある場合のXSLソート

<ResponseDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <resHead> 
     <id>R1983Rs</id> 
    </resHead> 
    <item> 
     <objRef> 
      <objId>100</objId> 
      <sysId>xyz</sysId> 
     </objRef> 
     <!-- Additional data here --> 
    </item> 
    <item> 
     <objRef> 
      <objId>140</objId> 
      <sysId>abc</sysId> 
     </objRef> 
     <!-- Additional data here --> 
    </item> 
    <resFoot> 
     <id>1234</id> 
    </resFoot> 
</ResponseDoc> 

:ここに私のXMLデータの簡易版です。結果のXMLファイルには、次のようになります。

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> 
    <xsl:template match="ResponseDoc"> 
     <xsl:copy> 
      <xsl:apply-templates select="resHead" /> 
      <xsl:apply-templates select="item"> 
       <xsl:sort select="number(objRef/objId)" order="descending" /> 
      </xsl:apply-templates> 
      <xsl:apply-templates select="resFoot" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="node() | @*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

しかし、スキーマがある場合、私は明示的に<resHead><resFoot>を処理するために必要とするので、これは不満足である:

<ResponseDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <resHead> 
     <id>R1983Rs</id> 
    </resHead> 
    <item> 
     <objRef> 
      <objId>140</objId> 
      <sysId>abc</sysId> 
     </objRef> 
     <!-- Additional data here --> 
    </item> 
    <item> 
     <objRef> 
      <objId>100</objId> 
      <sysId>xyz</sysId> 
     </objRef> 
     <!-- Additional data here --> 
    </item> 
    <resFoot> 
     <id>1234</id> 
    </resFoot> 
</ResponseDoc> 

私は、次のXSLスタイルシートを使用してソートすることに成功しました追加の兄弟を含めて<item>に拡張しました。このXSLを検索して変更する必要があります。私が見つけるしたい

... 
<items> 
    <item>...</item> 
    <item>...</item> 
    <item>...</item> 
</items> 
... 

:私は多くの研究が行われたがいずれか一方のみが任意の兄弟要素を含むORいくつかの「コンテナ」要素内の要素、すなわち「ソート」が含まれていない例を見つけてきましたソートを達成するためのより一般的な方法。私は作業スタイルシートの多くのバリエーションを試しましたが、私は兄弟ノードを失うか再配置するか、並べ替えを中断します。助けてもらえますか?ここで

答えて

0

は、すべてのitemの要素が連続している場合は動作しますソリューションです。

<xsl:template match="ResponseDoc"> 
    <xsl:copy> 
     <xsl:apply-templates select="item[1]/preceding-sibling::*" /> 
     <xsl:apply-templates select="item"> 
      <xsl:sort select="number(objRef/objId)" order="descending" /> 
     </xsl:apply-templates> 
     <xsl:apply-templates select="item[last()]/following-sibling::*" /> 
    </xsl:copy> 
</xsl:template> 

それは単に種の代わりにresHeadの最初のitem要素の前に来るすべての兄弟を、そして後に来るすべての兄弟最後にresFootの代わりにitemという要素があります。

+0

ありがとう!私がすでに持っていたものにシンプルで効果的な変更。私の 'item'要素は連続しています。 – CRW

0
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> 

    <xsl:template match="/"> 

    <xsl:for-each select="ResponseDoc"> 
     <xsl:sort select="item" order="descending" /> 

     <xsl:copy-of select="." /> 

    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 
+0

XSI宣言が緩んでいないと、すべてのノードに表示されます。 – Mike

関連する問題