私の(簡略化された)入力 XML ファイルには、次のものが含まれています。
<?xml version="1.0" encoding="UTF-8"?>
<main>
<DATA_RECORD>
<MESSAGE><pd> <cdhead version="13"/> </pd></MESSAGE>
</DATA_RECORD>
</main>
MESSAGE 要素の値は、文字エスケープされた XML インスタンスです。次の XML を表します。
<pd>
<cdhead version="13"/>
</pd>
入力 XML に xsl 変換を適用し、何らかの方法で MESSAGE コンテンツを変数に解析し、Xpath 式を使用してその詳細にアクセスしたいと考えています。
以下のように JavaScript 関数を追加しようとしましたが、スクリプトによって返されたオブジェクトは明らかに間違った DOM サブクラスです (下の結果を参照)。完全を期すために、DOM の内容を文字列として返す関数を追加しました。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:my="http://example.com/my"
exclude-result-prefixes="ms my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<ms:script language="JScript" implements-prefix="my">
<![CDATA[
function parseToDOM (input) {
var doc = new ActiveXObject('Msxml2.DOMDocument.6.0');
doc.loadXML (input);
return doc.documentElement;
};
function parseToXMLString (input) {
var doc = new ActiveXObject('Msxml2.DOMDocument.6.0');
doc.loadXML (input);
return doc.documentElement.xml;
};
]]>
</ms:script>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="DATA_RECORD">
<xsl:variable name="DOM"><xsl:copy-of select="my:parseToDOM (MESSAGE)"/></xsl:variable>
<xsl:variable name="XML"><xsl:copy-of select="my:parseToXMLString (MESSAGE)"/></xsl:variable>
<msg1><xsl:value-of select="$XML"/></msg1>
<msg2><xsl:value-of select="$XML" disable-output-escaping="yes"/></msg2>
<dom><xsl:copy-of select="$DOM"/></dom>
<version><xsl:value-of select="$DOM/pd/cdhead/@version"/></version>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
結果:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<msg1><pd>
<cdhead version="13"/>
</pd></msg1>
<msg2><pd>
<cdhead version="13"/>
</pd></msg2>
<dom/>
<version></version>
</root>
Jscript 関数が Xpath を使用できる結果を返すようにするにはどうすればよいですか?
ところで、エスケープされた XML 文字列を解析して Xpath を使用できる結果にする XSLT 1.0 関数はありますか?
添加
私はいくつかのバリエーションを試しており、解決策に近づいています。まず、Altova XMLSpy では xsl プロセッサーを選択でき、組み込みのものを使用すると上記の結果になりました。もちろん、MSXML 6.0 が必要ですが、それを選択すると、代わりに input.text を解析する必要があったため、エラーが発生しました。しかし、JavaScriptで余分なことをした後、結果でXpath式を使用できるようになっただけです。while<
などは etcetera に解析されますが<
、これだけでは適切な DOM の結果に到達できないことが判明しました。そのため、最初に入力文字列のエスケープを解除することにしました。
しかし、私は別の障害にぶつかりました。以下は正常に機能しますが、以下input.text
のリテラルの代わりに使用すると機能しません。
以下の xslt を参照してください。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:my="http://example.com/my"
exclude-result-prefixes="ms my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<ms:script language="JScript" implements-prefix="my">
<![CDATA[
function parseToDOM (input) {
var doc = new ActiveXObject('Msxml2.DOMDocument.6.0');
doc.loadXML (unescapeXML ('<pd> <cdhead version="13"/> </pd>'));
//doc.loadXML (unescapeXML (input.text));
return doc;
};
function unescapeXML (str) {
var ostr = str;
ostr = ostr.replace (/"/g, '"');
ostr = ostr.replace (/</g, '<');
ostr = ostr.replace (/=/g, '=');
ostr = ostr.replace (/>/g, '>');
return ostr;
};
]]>
</ms:script>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="DATA_RECORD">
<xsl:variable name="msg" select="my:parseToDOM (MESSAGE)"/>
<tst><xsl:value-of select="$msg/pd/cdhead/@version"/></tst>
</xsl:template>
</xsl:stylesheet>
今の結果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tst>13</tst>
</root>
これはまさに私が欲しいものです。
しかし、上で述べたように、リテラルの解析についてコメントし、代わりに入力を使用すると、次のようになります。
//doc.loadXML (unescapeXML ('<pd> <cdhead version="13"/> </pd>'));
doc.loadXML (unescapeXML (input.text));
次のエラーが表示されます (xslt パーサーとして MSXML 6.0 を使用する Altova XML Spy で):
XSL transformation failed due to following error:
Microsoft JScript runtime error
'undefined' is null or not an object
line = 10, col = 3 (line is offset from the start of the script block).
Error returned from property or method call.
最初の JavaScript の replace ステートメントを指します。
また、IE9 は以下を適切に処理できません。
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xslt"?>
<main>
<DATA_RECORD>
<MESSAGE><pd> <cdhead version="13"/> </pd></MESSAGE>
</DATA_RECORD>
</main>
このファイルを IE9 で開くと (ここで、test.xslt は入力が無視され、代わりにリテラルが処理される変換のバージョンであるため、XML Spy では問題ありません)、処理エラーが発生します。
XML5001: Applying Integrated XSLT Handling.
XSLT8690: XSLT processing failed.
これはなぜですか?どうすれば修正できますか?