2010-12-16 22 views
1

プラットフォーム:サクソン9 - XSLT 2.0ソートXML要素の順序XSLTベースの外部ドキュメントで指定された順序

私は定期的に、編集し、更新して保存する必要が3000件のXMLドキュメントを持っています。

処理の一部には、編集前にリポジトリから文書をチェックアウトし、編集が完了したときに定期的に文書を公開することが含まれます。

各ドキュメントには、セクションごとに名前の付いたセクションがあります。テキスト要素内の

<part> 
     <meta> 
      <place_id>12345</place_id> 
      <place_name>London</place_name> 
      <country_id>GB</country_id> 
      <country_name>United Kingdom</country_name> 
     </meta> 
     <text> 
      <docs>some blurb</docs> 
      <airport>some blurb LGW LHR</airport> 
      <trains>some blurb</trains> 
      <hotels>some blurb</hotels> 
      <health>some blurb</health> 
      <attractions>some blurb</attractions> 
     </text> 
    </part> 

がほぼ100セクションがあり、すべての編集チームと同じように、彼らは、時折、しかし、定期的に有利なために自分の心を変えます。おそらく年に2回。

現時点では、編集および出版のために、現在の優先順に編集者にXML文書セクションを提示します。この順序は、「stdhdg.xml」と呼ばれる動的に生成された外部ドキュメントに指定されており、このような何か表示されている:

<hdgs> 
    <hdg name="docs" newsort="10"/> 
    <hdg name="airport" newsort="30"/> 
    <hdg name="trains" newsort="20"/> 
    <hdg name="hotels" newsort="40"/> 
    <hdg name="health" newsort="60"/> 
    <hdg name="attractions" newsort="50"/> 
</hdgs> 

優先ソート順をHDG/@ newsortによって指定されます。

だから私は、正しい順序

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
<xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 
    <text> 
     <xsl:for-each select="$stdhead//hdg"> 
      <xsl:sort data-type="number" order="ascending" select="@newsort"/> 
      <xsl:variable name="tagname" select="@name"/> 
      <xsl:variable name="thisnode" select="$thetext/*[local-name() = $tagname]"/> 
      <xsl:apply-templates select="$thisnode"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

に処理するために、このようなテンプレートを使用ししかし、それは非常に遅く、面倒なようで、私はそれをスピードアップするためにキーを使用する必要があると感じています。

この並べ替え操作を行う方法は簡単です。

(編集者の編集方法を変更するために私に聞かないでください。それは私の人生の価値以上のものです)

TIA

Feargal

+0

良い質問、+1。すべての編集の前に再ソートの必要性を完全に排除するソリューションについては、私の答えを参照してください。 :) –

答えて

0

はい、キーは、このような検索をスピードアップする必要があります。

<xsl:stylesheet ...> 

    <xsl:key name="k1" match="text/*" use="local-name()"/> 

    <xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 

    ... 

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
    <text> 
     <xsl:for-each select="$stdhead//hdg"> 
      <xsl:sort data-type="number" order="ascending" select="@newsort"/> 
      <xsl:apply-templates select="key('k1', @name, $thetext)"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

</xsl:stylesheet> 

すべてがブラウザに直接入力されているので、テストされたコードではなく、アプローチする方法の概要として取り上げてください。

[編集]考え直したように、私はあなたがテキスト要素内

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:key name="k1" match="text/*" use="local-name()"/> 

    <xsl:variable name="stdhead" select="document('stdhdg.xml')"/> 

    <xsl:variable name="sorted-headers" as="element(hdg)*"> 
    <xsl:perform-sort select="$stdhead//hdg"> 
     <xsl:sort select="@newsort" data-type="number"/> 
    </xsl:perform-sort> 
    </xsl:variable> 

<xsl:template match="text"> 
    <xsl:variable name="thetext" select="."/> 
    <text> 
     <xsl:for-each select="$sorted-headers"> 
      <xsl:apply-templates select="key('k1', @name, $thetext)"/> 
     </xsl:for-each> 
    </text> 
</xsl:template> 

</xsl:stylesheet> 
+0

+1 'xsl:perform-sort'の例です。私は疑問に思っていますが、大きな文書であっても、この主要な使い方(文脈ノードの子供を選択する)は、メモリコストを忘れるような方法でプロセスをスピードアップすることになります。 –

+0

@アレジャンドロ:あなたは私の答え、みんなを読むことに興味があるかもしれません。 :) –

0

に変更することができるように ほぼ100のセクションがあり、あなたが処理するたびにソートtext要素が無駄だと思いますまた、 編集チームのすべてと同様に、 の心は優先順に に変更されることがありますが、これは定期的なものです。たぶん 年に2回。

。 。 。 。 。 。

しかし、それは編集のために提示されるたびに間違ったアプローチです。文書をソートすることは非常に 遅いと面倒なようで、私は私 が

それをスピードアップするためにキーを使用する必要があることを感じて

「stdhdg.xml」ドキュメントが変更されたときに、最も適切な解決策はソートして保存することです()。

「stdhdg.xml」の変化が組織的にうまく同期されない場合は、次の変換を実行し、繰り返し(たとえば毎日)仕事を持つことができます。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="vHeaderLoc" select="'file:///C:/temp/deleteMe/stdhdg.xml'"/> 

<xsl:variable name="vHeaderDoc" select= 
"document($vHeaderLoc)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "part/@hash 
      [not(. 
       = 
       string(document('file:///C:/temp/deleteMe/stdhdg.xml')) 
      ) 
      ]"> 
    <xsl:attribute name="hash"> 
    <xsl:value-of select="string($vHeaderDoc)"/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match= 
    "/*/text[not(/*/@hash 
       = string(document('file:///C:/temp/deleteMe/stdhdg.xml')) 
       ) 
      ]"> 
    <text> 
    <xsl:apply-templates select="*"> 
    <xsl:sort data-type="number" 
    select="$vHeaderDoc/*/hdg[@name=name(current())]"/> 
    </xsl:apply-templates> 
    </text> 
</xsl:template> 
</xsl:stylesheet> 

メインコンテンツXML文書です(

<part hash="010203040506"> 
    <meta> 
     <place_id>12345</place_id> 
     <place_name>London</place_name> 
     <country_id>GB</country_id> 
     <country_name>United Kingdom</country_name> 
    </meta> 
    <text> 
     <docs>some blurb</docs> 
     <airport>some blurb LGW LHR</airport> 
     <trains>some blurb</trains> 
     <hotels>some blurb</hotels> 
     <health>some blurb</health> 
     <attractions>some blurb</attractions> 
    </text> 
</part> 

とstdhdg.xmlファイルがです::トップ要素は今)hash属性を持って注意することはあり

<hdgs> 
    <hdg name="docs">10</hdg> 
    <hdg name="airport">30</hdg> 
    <hdg name="trains">20</hdg> 
    <hdg name="hotels">40</hdg> 
    <hdg name="health">60</hdg> 
    <hdg name="attractions">50</hdg> 
</hdgs> 

は、変換は、上記最新のハッシュあり、新たにソートされた主なコンテンツ生成:

<part hash="103020406050"> 
    <meta> 
     <place_id>12345</place_id> 
     <place_name>London</place_name> 
     <country_id>GB</country_id> 
     <country_name>United Kingdom</country_name> 
    </meta> 
    <text> 
     <docs>some blurb</docs> 
     <trains>some blurb</trains> 
     <airport>some blurb LGW LHR</airport> 
     <hotels>some blurb</hotels> 
     <attractions>some blurb</attractions> 
     <health>some blurb</health> 
    </text> 
</part> 

注意くださいを

  1. メインコンテンツドキュメントの先頭の要素hash属性があり、その値はstdhdg.xml文書にあるソートキーの連結です。

  2. stdhdg.xmlファイルの形式もわずかに変更され、キーの連結がドキュメントの文字列値として簡単に生成されます。

  3. メインコンテンツに保存されたハッシュがstdhdg.xmlのsort-keys-concatenationと同じ場合、日次実行変換は恒等変換です。

  4. 古いハッシュで、stdhdg.xmlのソートキーと一致しない場合は、新しいハッシュに更新され、セクションが再ソートされます。

関連する問題