2011-01-24 21 views
2

この問題は、how to unescape xml with xsltに記載されているものと似ていますが、私のテキストは処理命令から出てくるものと少し異なります。xslの文字をエスケープ処理する方法

私はこのような命令があります。

<?xm-mark data="&lt;p>Here is the text&lt;/p>" ?> 

を私は&lt;エンコードされていないと出力データ部分をしたいと思います。私の試みはこれまでのところです:

<xsl:template match="processing-instruction('xm-mark')"> 
    <mymark> 
    <xsl:value-of select="substring-before(substring-after(., 'data=&quot;'), '&quot;')" 
    disable-output-escaping="yes" /> 
    </mymark> 
</xsl:template> 

しかし、これは&lt;p>としてテキストを私に戻っています。私がdisable-output-escaping = "yes"を削除した場合、私は&amplt;(私が期待するように二重にコード化された)を返します。私はテンプレートの価値の価値を置くことができないので、どのようにデータをエスケープしたらいいのでしょうか?

+0

ここで誤解があると思います。「xsl:value-of」出力**テキストノード**とテキストノードには、適切なXML文書の中で**文字エンティティ**にエンコードする特殊文字「& 。いくつかの文字列を疑似XML "断片"ではなくポーズとして出力したい場合は、DOEメカニズムを使用してください。スマートデザイナーの中には、この ''と ''を '&'に変換する非解析擬似XML文字列を再エンコードすることを選択した場合、これをプリデコードする必要があります。これはすでに前に答えられました...私は検索します... –

+1

これはマークアップを破壊する悲劇的なケースです。分析と推奨される解決策については私の答えを参照してください。 –

+0

私はすべての処理命令とエンコードされた文字でxmlを作成していないし、サプライヤに変更を加える力を持っていないことは明らかです。エンコードを行うために.netで拡張を作成するのは簡単ですが、 "all xslt"ソリューションを望んでいました。 – Wavel

答えて

2

これは、マークアップをテキストに変換して破棄したときの結果です。

このような恐ろしいことを決して「建築」しないように注意してください。

はまた、DOEに頼ること(DOEは必須の機能ではなく、そのようなFFで使用されるものとして、いくつかの主要なXSLT 1.0プロセッサは、それを実装していない)絶望と全くis not guaranteed to workのサインです。

他の代替手段はありますか

可能な解決策の1つは、文字列をXMLとして解析し、結果のXMLドキュメントを返す拡張関数(XSLT/XPathバージョン1.0および2.0に標準機能はありません)を記述することです。 、

<xsl:copy-of select= 
     "xx:parse(substring-before(substring-after(., 'data=&quot;'), '&quot;'))/*"/> 
+0

私は.netを使ってxmlファイルを処理するので、おそらくC#で文字列をエンコードしない拡張機能を作成します。私はより純粋なxsltソリューションを試していました。そして、明確にするために、私はXMLを作成しませんでした!あなたはそれにある他の混乱を見なければなりません:) – Wavel

+0

@Wavel:はい、これは私が推奨する解決策です。 –

1

処理命令をエスケープする何かを必要としない、彼らはそのまま正確に扱われ<??>間の何に、コメントに似た構文解析されている:そのように使用されます。あなたができる場合は、代わりにこれを生成するために、その命令を生成しています何でも修正する必要があります。

<?xm-mark data="<p>Here is the text</p>" ?>

あなたがそれを行うことができない場合は、私もそれを解析するためにXSLTを使用しようとしないでしょう。

編集:あなたがここに必要以上に複雑になる可能性が高いので、おそらく明確にする必要があります:処理命令には属性がなく、最後のスペースも '処理命令ノードの「値」となります。実際にはxm-markという名前の命令とここではdata="<p>Here is the text</p>"という値があります(ここにはスペースは含まれていません)。dataも値の一部です<p>..</p>部分として

あなたのケースでは、おそらく処理命令ノードの値は、おそらくあなたが興味を持っているでしょう、<?xm-mark <p>Here is the text</p>?>で十分です。

EDIT:

<xsl:template match="processing-instruction('xm-mark')"> 
    <xsl:element name="mymark"> 
     <xsl:call-template name="unescape"> 
     <xsl:with-param name="input" select="substring-before(substring-after(., 'data=&quot;'), '&quot;')" /> 
     </xsl:call-template> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template name="unescape"> 
    <xsl:param name="input" /> 
    <xsl:choose> 
     <xsl:when test="contains($input, '&amp;lt;')"> 
     <xsl:call-template name="unescape"> 
      <xsl:with-param name="input" select="substring-before($input, '&amp;lt;')" /> 
     </xsl:call-template> 
     <xsl:text>&lt;</xsl:text> 
     <xsl:call-template name="unescape"> 
      <xsl:with-param name="input" select="substring-after($input, '&amp;lt;')" /> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="$input" /> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

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

NB:まあ、あなたはこれを試みることができるあなたはそれを参照するために&amp;を使用する必要がXSLTで処理する際&は、むしろマークアップよりもテキストとして採用されているので。したがって、処理命令の値は、xml文書で 'そのまま'出力された場合、実際には&amp;lt;p&gt;etc..と表されます。上記のxslは少なくとも&lt;p&gt;etc..に変換されますが、実際のpタグが必要な場合は、拡張メソッドを使用してください。

+0

私は指示を生成していたものを修正することができれば嬉しいです!ああ、完璧な世界のために:)残念ながら、私は私が得たものを手に入れ、そのようにしなければなりません。 – Wavel

+0

PIの値が特殊文字をエスケープする必要がないことを指摘するため+1。 –

+0

@Wavel:これは悪い解決策ですが、DOEの前に '& lt; ''文字列を '<'文字(その他の特殊文字も同様)に置き換えることができます。 –

関連する問題