0

少し問題があります。XMLのノードに整数が含まれている可能性があり、この整数を文字列に置き換える必要があります。各番号は文字列と一致します。

たとえば、私は持っています:


整数-文字列

1-TODO

2-進行中

3-完了

4-エラー

5-中止


元のXML:

    <root>
       <status>1</status>
    </root>

変換されたXML:

    <root>
       <status>TODO</status>
    </root>

だから私は1を「TODO」に、2を「INPROGRESS」に置き換えたい...

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:template match="/root/status">
    <root>
      <status>
                <xsl:variable name="text" select="." />

                <xsl:choose>
                    <xsl:when test="contains($text, '1')">

                        <xsl:value-of select="'TODO'"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$text"/>
                    </xsl:otherwise>
                </xsl:choose>
    </status></root>
            </xsl:template>
    </xsl:stylesheet>

私はそれをする別の方法があるかどうか尋ねています。

4

7 に答える 7

3

これを行うにはいくつかの方法があります。変換が1からNの範囲の連続する整数からのものである場合、私は使用します

<xsl:variable name="index" select="xs:integer(status)"/>
<xsl:value-of select="('TODO', 'IN PROGRESS', 'DONE', 'ERROR', 'ABORTED')[$index]"/>

値の数が少ない他の場合は、テンプレートルールを使用できます。

<xsl:template match="status[.='1']" mode="lookup">TODO</xsl:template>
<xsl:template match="status[.='2']" mode="lookup">IN PROGRESS</xsl:template>

その他の場合、ルックアップテーブルは理にかなっています(面倒なdocument('')呼び出しを伴うDimitreのバージョンはXSLT1.0用に設計されていることに注意してください-2.0を使用している場合はかなり簡単です。通常は2.0を想定し、Dimitreは通常1.0を想定しています。)

「=」を意味するときにcontains()を使用するという間違いを犯す人が増えています。ノードのコンテンツが「X」であるかどうかをテストする場合は$node = "X"、ではなくを使用しますcontains($node, "X")

于 2012-08-31T18:51:04.997 に答える
2

これを行う1つの方法は、一種の「ルックアップ」値テーブルを作成することです。これは、XSLTに埋め込むことも、別のファイルに入れることもできます。たとえば、XSLTファイルに入れると、次のようになります。

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

<lookup:data>
   <status code="1">TO DO</status>
   <status code="2">IN PROGRESS</status>
   <status code="3">DONE</status>
</lookup:data>

次に、このデータにアクセスするための変数も作成します

<xsl:variable name="lookup" select="document('')/*/lookup:data"/>

最後に、値を調べるには、これを行うだけです。

<xsl:value-of select="$lookup/status[@code = '1']/>

この場合の完全なXSLTは次のとおりです

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

   <xsl:output method="xml" indent="yes"/>

   <lookup:data>
      <status code="1">TO DO</status>
      <status code="2">IN PROGRESS</status>
      <status code="3">DONE</status>
   </lookup:data>

   <xsl:variable name="lookup" select="document('')/*/lookup:data"/>

   <xsl:template match="status/text()">
      <xsl:value-of select="$lookup/status[@code = current()]" />
   </xsl:template>

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

サンプルXMLに適用すると、次のように出力されます。

<root>
   <status>TODO</status>
</root>  

ただし、これらを別のファイルに入れておくと、他のスタイルシートで再利用できるため、より良い場合があります。これを行うには、「lookup.xml」というファイルを作成し、XMLを追加するだけです。

<data>
   <status code="1">TO DO</status>
   <status code="2">IN PROGRESS</status>
   <status code="3">DONE</status>
</data>

この場合、名前空間は必要ないことに注意してください。次に、変数の定義を次のように変更します。

<xsl:variable name="lookup" select="document('lookup.xml')/data"/>
于 2012-08-31T15:47:32.873 に答える
1

ソリューションに不要なコードがたくさんあります。以下は、同じように機能する簡略化されたバージョンです。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
        <xsl:template match="/root/status"> 
<root> 
  <status> 
            <xsl:choose> 
                <xsl:when test="contains(.,'1')">TODO</xsl:when> 
                <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise> 
            </xsl:choose> 
  </status>
 </root> 
        </xsl:template> 
</xsl:stylesheet> 
于 2012-08-31T15:58:45.700 に答える
0

最も簡単なアプローチは、ID変換から始めて、特別なケースを追加することです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="status[. = '1']">
    <status>TODO</status>
  </xsl:template>
  <!-- likewise for status[. = '2'] etc. -->

  <!-- copy everything else -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
于 2012-08-31T15:36:53.970 に答える
0

XSLTバージョン3.0では、次のmapタイプを使用できます。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:variable name="MyMap" select="
    map { 
      '1' : 'TODO', 
      '2' : 'IN PROGRESS',
      '3' : 'DONE',
      '4' : 'ERROR',
      '5' : 'ABORTED'}">
  </xsl:variable>

  <xsl:template match="/root/status">
    <status>
      <xsl:variable name="text" select="."/>
      <xsl:value-of select="$MyMap( $text )"/>
    </status>
  </xsl:template>
</xsl:stylesheet>
于 2018-12-04T14:15:54.930 に答える
-1

私の言葉。XSLTは簡単ではなく、他のいくつかの回答に示されているように、内部の仕組みに関する知識を披露することによって、必要以上に難しくするべきではないと思います。

頭に釘を打ちやすいように、Chooseステートメントを使用します。テストを簡単にし、コードを少しクリーンアップして読みやすくするために、おそらく別のテンプレートに引き出します(他の言語のメソッドと同じように使用します)。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="PrintStatus">
  <!-- param we can pass a value into or default to the current node -->
  <xsl:param name="text" select="." />  
  <xsl:choose>
    <xsl:when test="contains($text, '1')">
      <xsl:value-of select="'TODO'"/>
    </xsl:when>
    <!-- Assume your others go here -->
    <xsl:otherwise>
      <xsl:value-of select="$text"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="/root/status">
  <root>
    <status>
      <xsl:call-template name="PrintStatus" />
    </status>
  </root>
</xsl:template>

</xsl:stylesheet>

あなたが余分な合併症を必要としない限り、それを単純にしてください。

于 2012-08-31T16:50:14.417 に答える
-1

このような場合に私が時々使用するトリックは、1つの文字列で値のリストを使用し、次のように部分文字列を取得することです。

<xsl:variable name="statuslist">TODO       IN PROGRESSDONE       ERROR      ABORTED    </xsl:variable>

<xsl:template match="status/text()">
  <xsl:value-of select="normalize-space(substring($statuslist, ( . - 1 ) * 11 , 11))" />
</xsl:template>

'statuslist'の値は正確に11文字離れている(最長値の長さ)ため、サブストリングの* 11と、11に注意してください。0ではなく1から数えるため、インデックスから1を引く必要があります。または、1を引くのではなく、最初に11個のスペースで変数を埋めることもできます。それはあなた次第です。呼び出しはnormalize-space、抽出された値から余分なスペースを取り除くだけです。

きちんと整理したい場合は、各値の間に区切り文字を入れて、代わり*12,11にそのsubstring呼び出しで使用できます。

可能な値が多数ある場合、これは適切にスケーリングするソリューションではありません。明らかに、可能なIDを順番に並べる必要がありますが、値が少ない場合はかなりコンパクトです。

于 2012-08-31T18:07:27.153 に答える