4

16進文字列のバリアントを含む文字列がいくつかあります(ソースはフレームメーカーです)。したがって、文字列は次のようになります。

これは16進コード\x27の文であり、修正する必要があります。

に変更する必要があります

これはいくつかの16進コードを含む文であり、修正する必要があります。

実際には、これらのいくつかが1つの文字列に含まれている可能性があるため、テキストをウォークスルーし、すべての16進コード(\ x ##のように見える)をキャプチャして、これらのコードをすべて正しい文字に置き換えるための最良の方法を探しています。 。次のように、すべての文字を含むxmlリスト/ルックアップテーブルを作成しました。

<xsl:param name="reflist">
    <Code Value="\x27">'</Code>
<Code Value="\x28">(</Code>
<Code Value="\x29">)</Code>
<Code Value="\x2a">*</Code>
<Code Value="\x2b">+</Code>
    <!-- much more like these... -->
</xsl:param>

今のところ、単純な置換引数を使用しましたが、文字が多すぎてこれを機能させることができません。

これを行うための最良の方法は何ですか?

4

2 に答える 2

5

次のように、「参照テーブル」の使用を完全に避けることができます。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:my="my:my" exclude-result-prefixes="my xs">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="text()[matches(.,  '\\x(\d|[a-f])+')]">
   <xsl:analyze-string select="." regex="\\x(\d|[a-f])+" >
     <xsl:matching-substring>
       <xsl:value-of select=
       "codepoints-to-string(my:hex2dec(substring(.,3), 0))"/>
     </xsl:matching-substring>
     <xsl:non-matching-substring>
      <xsl:value-of select="."/>
     </xsl:non-matching-substring>
   </xsl:analyze-string>
 </xsl:template>

 <xsl:function name="my:hex2dec" as="xs:integer">
  <xsl:param name="pStr" as="xs:string"/>
  <xsl:param name="pAccum" as="xs:integer"/>

  <xsl:sequence select=
   "if(not($pStr))
     then $pAccum
     else
      for $char in substring($pStr, 1, 1),
          $code in
            if($char ge '0' and $char le '9')
              then xs:integer($char)
              else
                string-to-codepoints($char) - string-to-codepoints('a') +10
       return
          my:hex2dec(substring($pStr,2), 16*$pAccum + $code)
   "/>
 </xsl:function>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用される場合:

<t>
 <p>this is some sentence with some hex code\x27 s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x28 s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x29 s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2a s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2b s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2c s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2d s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2e s ,
    and we need that fixed.</p>
 <p>this is some sentence with some hex code\x2f s ,
    and we need that fixed.</p>
</t>

必要な正しい結果が生成されます。

<t>
   <p>this is some sentence with some hex code' s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code( s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code) s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code* s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code+ s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code, s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code- s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code. s ,
    and we need that fixed.</p>
   <p>this is some sentence with some hex code/ s ,
    and we need that fixed.</p>
</t>

注意してください:

この変換は一般的なもので、16 進数の Unicode コードを正しく処理できます。

たとえば、この XML ドキュメントに同じ変換を適用すると、次のようになります

<t>
 <p>this is some sentence with some hex code\x0428\x0438\x0448 s ,
    and we need that fixed.</p>
</t>

正しい結果 (キリル文字で「グリル」を表すブルガリア語を含む) が生成されます。

<t>
   <p>this is some sentence with some hex codeШиш s ,
    and we need that fixed.</p>
</t>
于 2012-11-10T05:18:06.860 に答える
3

analyze-stringのように使用

<xsl:template match="text()">
  <xsl:analyze-string select="." regex="\\x[0-9a-f]{{2}}" flags="i">
    <xsl:matching-substring>
      <xsl:value-of select="$reflist/Code[@Value = .]"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:template>

キーを使用することもお勧めします。

<xsl:param name="reflist" as="document-node()">
  <xsl:document>
    <Root>
      <Code Value="\x27">'</Code>
      <Code Value="\x28">(</Code>
      <Code Value="\x29">)</Code>
      <Code Value="\x2a">*</Code>
      <Code Value="\x2b">+</Code>
      <!-- much more like these... -->
    </Root>
  </xsl:document>
</xsl:param>

<xsl:key name="code-by-value" match="Code" use="@Value"/>

次に、ルックアップを改善できます

<xsl:template match="text/text()">
  <xsl:analyze-string select="." regex="\\x[0-9a-f]{{2}}" flags="i">
    <xsl:matching-substring>
      <xsl:value-of select="key('code-by-value', ., $reflist)"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:template>

入力が

<root>
  <text>this is some sentence with some hex code\x27 s , and we need that \x28and this\x29 fixed.</text>
</root>

完全なスタイルシートは

<xsl:stylesheet 
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">

<xsl:param name="reflist" as="document-node()">
  <xsl:document>
    <Root>
      <Code Value="\x27">'</Code>
      <Code Value="\x28">(</Code>
      <Code Value="\x29">)</Code>
      <Code Value="\x2a">*</Code>
      <Code Value="\x2b">+</Code>
      <!-- much more like these... -->
    </Root>
  </xsl:document>
</xsl:param>

<xsl:key name="code-by-value" match="Code" use="@Value"/>

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

<xsl:template match="text/text()">
  <xsl:analyze-string select="." regex="\\x[0-9a-f]{{2}}" flags="i">
    <xsl:matching-substring>
      <xsl:value-of select="key('code-by-value', ., $reflist)"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:template>

</xsl:stylesheet>

Saxon 9.4 は、入力を次のように変換します。

<root>
  <text>this is some sentence with some hex code' s , and we need that (and this) fixed.</text>
</root>
于 2012-11-09T15:15:02.773 に答える