CDATA
XSL を使用して XML ノードのコンテンツを取得しようとしています。現在、ノードは次のようになっています。
<node id="1" text="Book Information" ><![CDATA[This is sample text]]></node>
私はThis is sample text
作品が必要です。誰かこれについて何か考えがありますか?
前もって感謝します。
このスタイルシートを使用すると、次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="node/text()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
この XML ファイルで:
<?xml version="1.0" encoding="utf-8"?>
<node id=1 text="Book Information" ><![CDATA[This is sample text]]></node>
id=1
が無効な XMLであるため、解析エラーが発生します。
属性値 ( id="1"
) を引用符で囲み、スタイルシートを再実行すると、次のような出力が得られます。
これはサンプルテキストです
ということでスタートです。基本的に、CDATA をテキスト ノードとして扱うだけで、すぐに使用できます。
あなたが言った:
私は次のようなものを見つけました:
<xsl:output cdata-section-elements="text"/>
そして、CDATA をフェッチするには:
<xsl:value-of select="node" />
このアプローチは、使用value-of
している場合でも問題なく機能します。value-of
代わりに使用して、コメントの行に沿った例を次に示します。ただし、これcdata-section-elements
は出力側でのみ機能し、プレーンな古い文字データではなく CDATA セクションとして出力する出力XML 要素を示していることに注意してください。データの取得とは関係ありません。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output cdata-section-elements="foo"/>
<xsl:template match="/">
<foo>
<xsl:value-of select="node"/>
</foo>
</xsl:template>
</xsl:stylesheet>
プリントアウト
<?xml version="1.0"?>
<foo><![CDATA[This is sample text]]></foo>
これを達成するための他の簡単な手順。
W3cschoolsエディタを使って試してみました
。
サンプル XML ファイル:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<disk id="title"><![CDATA[Sample xml]]></disk >
<disk id="artist"><![CDATA[Vijay]]></disk >
</cd>
</catalog>
サンプル XSL ファイル:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="/catalog/cd/disk[@id='title']"/></td>
<td><xsl:value-of select="/catalog/cd/disk[@id='artist']"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
最終結果は次のとおりです。
出力CDATAセクションの場合:
を使用する必要がありますxsl:output/@cdata-section-elements
。http://www.w3.org/TR/xslt#outputから
cdata-section-elements属性には、空白で区切られたQNameのリストが含まれています。各QNameは、QNameが発生するxsl:output要素で有効な名前空間宣言を使用して拡張名に展開されます。デフォルトのネームスペースがある場合、プレフィックスを持たないQNameに使用されます。拡張は、複数のxsl:output要素を単一の有効なxsl:output要素にマージする前に実行されます。テキストノードの親の展開名がリストのメンバーである場合、テキストノードはCDATAセクションとして出力される必要があります。
もちろん、DOE以外にも。
XPathでCDATAセクションを選択することはできません。http://www.w3.org/TR/xpath/#data-modelによると
ノードには7つのタイプがあります。
ルートノード
要素ノード
テキストノード
属性ノード
名前空間ノード
処理命令ノード
コメントノード
そしてhttp://www.w3.org/TR/xpath/#section-Text-Nodesから
CDATAセクション内の各文字は、文字データとして扱われます。したがって、
<![CDATA[<]]>
ソースドキュメントでは<と同じように扱われます。どちらの場合も、ツリーのテキストノードに単一の<文字が含まれます。したがって、CDATAセクションは、<![CDATA[
と]]>
が削除され、とのすべての出現がそれぞれ<
とに&
置き換えられた かのように扱われます。<
&
私がウェブ上で見つけた唯一の解決策はこれです -
{XSLT}
<title>
<xsl:text disable-output-escaping="yes"><![CDATA[ <![CDATA[ ]]></xsl:text>
<xsl:value-of select="label" disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[]]]]><![CDATA[>]]></xsl:text>
</title>
ただし、特に XSLT のさまざまな部分でこれを実装する必要がある場合、これは最もクリーンなソリューションではありません。また、入力 XML に既に CDATA がある場合 (つまり、CDATA を保持しようとしている場合)、disable-output-escaping を使用しても機能しません。その時点までに、CDATA は XSLT エンジンによって既に解析されており、すべてが残っているからです。 xml を壊す可能性のあるコンテンツです。
これが私の解決策です-
XSLT の使用方法によっては、外部関数や注入関数を使用することができます。そうすることで、記述しているコードの量を簡単に最小限に抑えることができ、よりきれいなテンプレートを作成できます。
{C#}
public string CDATAWrap(string data)
{
return "<![CDATA[" + data + "]]>";
}
{XSLT}
<title>
<xsl:value-of select="CDataType:CDATAWrap(label)" disable-output-escaping="yes" />
</title>
私はさまざまな組み合わせを試し、これに対する解決策を得ました。
<xsl:value-of select="/node/."/>