4

コードを番号順に並べ替える必要があります。コードには、4 つの文字と 4 つの数字があります。

例えば、

COMP2100
COMP2400
COMP3410
LAWS2202
LAWS2250

実行する<xsl:sort select="code" order="ascending" /> と、結果の上に表示されます。

しかし、私はそれが「数字順」であることを望んでいます

COMP2100
LAWS2202
COMP2250
COMP2400
COMP3410

どうすればいいですか?

4

2 に答える 2

9

注: OP はサンプル XML を提供するようになりました。以下の理論は、この XML に簡単に適用できます。

I. XSLT 1.0 (パート 1)

これは、あなたの主張(「コードには4つの文字と4つの数字があります」)が常に当てはまると仮定する簡単なソリューションです。

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

  <xsl:variable name="vNums" select="'1234567890'" />

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

  <xsl:template match="/*">
    <t>
      <xsl:apply-templates>
        <xsl:sort select="substring(., 5)"
          data-type="number" />
      </xsl:apply-templates>
    </t>
  </xsl:template>
</xsl:stylesheet> 

...想像上の XML ドキュメントに適用され、ランダムな順序でシャッフルされます。

<?xml version="1.0" encoding="utf-8"?>
<t>
  <i>COMP3410</i>
  <i>LAWS2202</i>
  <i>COMP2400</i>
  <i>COMP2100</i>
  <i>LAWS2250</i>
</t>

...正しい結果が生成されます。

<?xml version="1.0" encoding="utf-8"?>
<t>
  <i>COMP2100</i>
  <i>LAWS2202</i>
  <i>LAWS2250</i>
  <i>COMP2400</i>
  <i>COMP3410</i>
</t>

説明:

  • XSLT の最も基本的なデザイン パターンのIdentity Transform1 つである (そうでない場合) はすべてのノードをソース XML ドキュメントから結果の XML ドキュメントにそのままコピーします。
  • <t>1 つのテンプレートは、文字列内の文字に基づいて位置 5 から文字列の末尾までのすべての子を並べ替えることによって、Identity Transform をオーバーライドします。

繰り返しますが、この解決策は、元の主張-「コードには4つの文字と4つの数字があります」-が真実である(そして常に真実である)ことを前提としていることに注意してください。


Ⅱ.XSLT 1.0 (パート 2)

<i>(潜在的に) より安全な解決策は、ノード内のさまざまな位置に数字以外の文字が多数存在する可能性があると想定することです。その場合、この XSLT:

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

  <xsl:variable name="vNums" select="'1234567890'" />

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

  <xsl:template match="/*">
    <t>
      <xsl:apply-templates>
        <xsl:sort select="translate(., translate(., $vNums, ''), '')"
          data-type="number" />
      </xsl:apply-templates>
    </t>
  </xsl:template>
</xsl:stylesheet>

...同じ結果が得られます。

<?xml version="1.0" encoding="utf-8"?>
<t>
  <i>COMP2100</i>
  <i>LAWS2202</i>
  <i>LAWS2250</i>
  <i>COMP2400</i>
  <i>COMP3410</i>
</t>

説明:

  • Identity Transformが再び使用されます。
  • この場合、追加のテンプレートはいわゆるDouble Translate Method(Michael Kay によって最初に提案され、Dimitre Novatchev によって最初に示されました) を使用して、<i>並べ替えの前に各要素の値からすべての非数値文字を削除します。

III. XSLT 2.0 ソリューション

XSLT 2.0 ソリューションは、XSLT 1.0 ソリューションのパート 2 と非常によく似ています。Double Translate メソッドを正規表現を処理する XPath 2.0 の機能に置き換えるだけです。

<xsl:sort select="replace(., '[^\d]', '')" data-type="number" />

XPath 2.0 で正規表現を使用する必要は決してないことに注意してください。Double Translate Method は、XPath 1.0 と同様に機能します。ただし、このreplace()方法はおそらくより効率的です。

于 2012-09-16T19:33:01.177 に答える
3

提供された XSLT コードには、次の 2 つの明らかなエラーがあります

  1. 要素の選択に使用される名前空間は、提供された XML ドキュメントの既定の名前空間とは異なります。xmlns:xsi="file://Volumes/xxxxxxx/Assignment":を に変更するだけxmlns:xsi="file://Volumes/xxxxxxx/Assignment"です。

  2. 現在のソートは数値ではありません。変化する:

    <xsl:sort select="xsi:code" order="ascending" />

に:

   <xsl:sort select="substring(xsi:code, 5)" data-type="number" />

完全な変換は次のようになります。

<xsl:stylesheet version="1.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:xsi="file://Volumes/u4783938/Assignment">
<xsl:template match="/">
    <html>
    <head>
        <title> Course Catalogue </title>
    </head>
    <body bgcolor="#FF9999">
        <h1> <div style="text-align:center"> Course Catalogue </div> </h1>
        <xsl:for-each select="xsi:catalogue/xsi:course">
        <xsl:sort select="substring(xsi:code, 5)"
         data-type="number" />
        <div style="width:1000px;margin-bottom:4px;color:white;background-color:#F36;text-align:justify;border:outset;margin-left:auto;margin-right:auto;">
            <xsl:apply-templates select="xsi:code" />
            <br />
            <xsl:apply-templates select="xsi:title" />
            <br />
            <xsl:apply-templates select="xsi:year" />
            <br />
            <xsl:apply-templates select="xsi:science" />
            <br />
            <xsl:apply-templates select="xsi:area" />
            <br />
            <xsl:apply-templates select="xsi:subject" />
            <br />
            <xsl:apply-templates select="xsi:updated" />
            <br />
            <xsl:apply-templates select="xsi:unit" />
            <br />
            <xsl:apply-templates select="xsi:description" />
            <br />
            <xsl:apply-templates select="xsi:outcomes" />
            <br />
            <xsl:apply-templates select="xsi:incompatibility" />
        </div>
        </xsl:for-each>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

この XML ドキュメントに適用すると、次のようになります

<catalogue xmlns="file://Volumes/u4783938/Assignment"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="file://Volumes/u4443554/Assignment/courses.xsd">
    <course>
        <code>ABCD3410</code>
        <title> Information Technology in Electronic Commerce </title>
        <year>later year</year>
        <science>C</science>
        <area> Research School of Computer Science </area>
        <subject> Computer Science </subject>
        <updated>2012-03-13T13:12:00</updated>
        <unit>6</unit>
        <description>Tce </description>
        <outcomes>Up trCommerce. </outcomes>
        <incompatibility>COMP1100</incompatibility>
    </course>
    <course>
        <code>COMP2011</code>
        <title> Course 2011 </title>
        <year>Year 2011</year>
        <science>C++</science>
        <area> Research School of Computer Science </area>
        <subject> Computer Science </subject>
        <updated>2012-03-13T13:12:00</updated>
        <unit>6</unit>
        <description>Tce </description>
        <outcomes>Up trCommerce. </outcomes>
        <incompatibility>COMP1100</incompatibility>
    </course>
</catalogue>

生成された結果は、コース コードの数値部分で正しくソートされるようになりました。

<html xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsi="file://Volumes/u4783938/Assignment">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

      <title> Course Catalogue </title>
   </head>
   <body bgcolor="#FF9999">
      <h1>
         <div style="text-align:center"> Course Catalogue </div>
      </h1>
      <div style="width:1000px;margin-bottom:4px;color:white;background-color:#F36;text-align:justify;border:outset;margin-left:auto;margin-right:auto;">COMP2011<br> Course 2011 <br>Year 2011<br>C++<br> Research School of Computer Science <br> Computer Science <br>2012-03-13T13:12:00<br>6<br>Tce <br>Up trCommerce. <br>COMP1100
      </div>
      <div style="width:1000px;margin-bottom:4px;color:white;background-color:#F36;text-align:justify;border:outset;margin-left:auto;margin-right:auto;">ABCD3410<br> Information Technology in Electronic Commerce <br>later year<br>C<br> Research School of Computer Science <br> Computer Science <br>2012-03-13T13:12:00<br>6<br>Tce <br>Up trCommerce. <br>COMP1100
      </div>
   </body>
</html>
于 2012-09-16T20:27:47.980 に答える