0

簡単な質問: xml 入力ファイルで未加工のアンパサンドを処理する方法。

追加: アンパサンドでフィールドを選択することすらありません。パーサーは、ファイル内にアンパサンドが存在すると不平を言います。

長い説明: URL 応答を介して生成された xml を扱っています。

<NOTE>I%20hope%20this%20won%27t%20require%20a%20signature%3f%20%20
There%20should%20be%20painters%20%26%20stone%20guys%20at%20the
%20house%20on%20Wednesday%2c%20but%20depending%20on%20what%20time%20
it%20is%20delivered%2c%20I%20can%27t%20guarantee%21%20%20
Also%2c%20just%20want%20to%20make%20sure%20the%20billing%20address
%20is%20different%20from%20shipping%20address%3f
</NOTE>

これは、これにデコードされた URL です。

<NOTE>I hope this won't require a signature?  
There should be painters & stone guys at the 
house on Wednesday, but depending on what time it is delivered, I can't guarantee!  
Also, just want to make sure the billing address is different from shipping address?  
</NOTE>

問題: xslproc は、「画家と石の男」の「&」が原因で、最後の文字列でチョークし、次のエラーが表示されます。

xmlParseEntityRef: no name
<NOTE>I hope this won't require a signature?  There should be painters &

xsltproc が終了を予期しているようです</NOTE>

disable-output-escaping="yes"いろいろな場所であらゆる方法を試しました。xsl:outputxsl:value-of

また、試しxsltproc --decode-uriてみましたが、それを理解することはできません。ドキュメントはありません。

注: 入力を urlencoded 形式で保持する価値があるかどうか疑問に思います。そして、次のような DOCTYPE を使用します (方法がわからない)。出力は最終的にブラウザです。

<!DOCTYPE xsl:stylesheet  [
    <!ENTITY nbsp   "&#160;">
    <!ENTITY copy   "&#169;">
    <!ENTITY reg    "&#174;">
]>
4

1 に答える 1

0

エスケープされていないアンパサンドがある場合、XML は不正な形式です。文字列を の中に入れると、<![CDATA[]]>うまくいくはずです。

<NOTE><![CDATA[I hope this won't require a signature?  
  There should be painters & stone guys at the 
  house on Wednesday, but depending on what time it is delivered, I can't guarantee!  
  Also, just want to make sure the billing address is different from shipping address?]]>  
</NOTE>

または、もちろん、の&amp;代わりに使用し&ます。

編集: XSLT プロセッサが disable-output-escaping をサポートしている場合 (および xsltproc がサポートしている場合)、URL エスケープを数字参照に変換することもできます。

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

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

  <xsl:template match="NOTE">
    <xsl:copy>
      <xsl:call-template name="decodeURL"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="decodeURL">
    <xsl:param name="URL" select="string()"/>
    <xsl:choose>
      <xsl:when test="contains($URL,'%')">
        <xsl:variable name="remainingURL" select="substring-after($URL,'%')"/>
        <xsl:value-of disable-output-escaping="yes" select="concat(
          substring-before($URL,'%'),
          '&amp;#x',
          substring($remainingURL,1,2),
          ';')"/>
        <xsl:call-template name="decodeURL">
          <xsl:with-param name="URL" select="substring($remainingURL,3)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$URL"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

もちろん、この変換を前処理ステップとして使用する必要はありませんdecodeURL。URL エンコードされた文字列を含むソース XML を HTML などに変換するスタイルシートで再利用できます。

于 2012-12-04T06:28:20.783 に答える