1

入力:

<text>
    Please see the registered mark® .
    Please see the copy right ©.
    Please see the Trade mark™.
</text>

出力:

  <text>
        Please see the registered mark<registeredTrademark></registeredTrademark>.
        Please see the copy right <copyright></copyright>.
        Please see the Trade mark <trademark></trademark>.
  </text>

上記のように、すべての特殊記号を要素に置き換える必要があります

誰でも助けることができますか。

ありがとう

4

2 に答える 2

2

これは XSLT 1.0 であるため、再帰的な名前付きテンプレートを使用して各文字を順番にチェックする必要があります。

まず、XSLT で一種の「ルックアップ」を作成する方が柔軟な場合があります。そこでは、シンボルのリストとそれらを置き換えるために必要な要素名を指定できます。

<lookup:codes>
  <code symbol="®">registeredTrademark</code>
  <code symbol="©">copyright</code>
  <code symbol="™">trademark</code>
</lookup:codes>

('lookup' 名前空間は、XSLT で宣言されている限り、実際には任意の名前を付けることができます)。

次に、これにアクセスするために、このルックアップにアクセスする変数を定義できます

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

そして、シンボルに基づいて実際のコードを検索するには、次のようにします ($text) は、チェックしているテキストを含む変数です。

  <xsl:variable name="char" select="substring($text, 1, 1)"/>
  <xsl:variable name="code" select="$lookup/code[@symbol = $char]"/>

名前付きテンプレートが行うことは、テキストの最初の文字をチェックし、ルックアップに存在する場合は要素に置き換えてから、テキストの残りの部分でテンプレートを再帰的に呼び出すことだけです。

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:lookup="lookup" exclude-result-prefixes="lookup">
   <xsl:output method="xml" indent="no"/>

   <lookup:codes>
      <code symbol="®">registeredTrademark</code>
      <code symbol="©">copyright</code>
      <code symbol="™">trademark</code>
   </lookup:codes>

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

   <xsl:template match="text[text()]">
      <text>
         <xsl:call-template name="text"/>
      </text>
   </xsl:template>

   <xsl:template name="text">
      <xsl:param name="text" select="text()"/>
      <xsl:variable name="char" select="substring($text, 1, 1)"/>
      <xsl:variable name="code" select="$lookup/code[@symbol = $char]"/>
      <xsl:choose>
         <xsl:when test="$code"><xsl:element name="{$code}" /></xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$char"/>
         </xsl:otherwise>
      </xsl:choose>
      <xsl:if test="string-length($text) &gt; 1">
         <xsl:call-template name="text">
            <xsl:with-param name="text" select="substring($text, 2, string-length($text) - 1)"/>
         </xsl:call-template>
      </xsl:if>
   </xsl:template>

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

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

<text> 
    Please see the registered mark<registeredTrademark /> . 
    Please see the copy right <copyright />. 
    Please see the Trade mark<trademark />. 
</text>
于 2012-08-08T09:56:26.420 に答える
1

この変換は、文字ごとの再帰を回避し、「最大可能ステップ」再帰を使用することで、より効率的になります

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

 <my:reps>
  <r char="®">registeredTrademark</r>
  <r char="©">copyright</r>
  <r char="™">trademark</r>
 </my:reps>

 <xsl:variable name="vReps" select="document('')/*/my:reps/*"/>

 <xsl:template match="text()" name="multReplace">
  <xsl:param name="pText" select="."/>
  <xsl:param name="pReps" select="$vReps"/>

   <xsl:if test="$pText">
     <xsl:variable name="vTarget" select="$pReps[1]/@char"/>
       <xsl:choose>
         <xsl:when test="not($vTarget)">
           <xsl:value-of select="$pText"/>
         </xsl:when>
         <xsl:otherwise>
           <xsl:variable name="vReplacement" select="$pReps[1]"/>

           <xsl:call-template name="multReplace">
            <xsl:with-param name="pText" select=
            "substring-before(concat($pText, $vTarget), $vTarget)"/>
            <xsl:with-param name="pReps" select="$pReps[position() >1]"/>
           </xsl:call-template>

           <xsl:if test="contains($pText, $vTarget)">
             <xsl:element name="{$vReplacement}"/>
             <xsl:call-template name="multReplace">
              <xsl:with-param name="pText" select="substring-after($pText, $vTarget)"/>
              <xsl:with-param name="pReps" select="$pReps"/>
             </xsl:call-template>
           </xsl:if>
         </xsl:otherwise>
       </xsl:choose>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用すると、次のようになります。

<text>
        Please see the registered mark® .
        Please see the copy right ©.
        Please see the Trade mark™.
</text>

正しく置換されたテキストが生成されます:

    Please see the registered mark<registeredTrademark/> .
    Please see the copy right <copyright/>.
    Please see the Trade mark<trademark/>.
于 2012-08-08T13:11:57.870 に答える