- PR -

XSLTでDOCTYPE宣言をコピーする方法はありませんか

1
投稿者投稿内容
ryu
会議室デビュー日: 2003/02/01
投稿数: 4
投稿日時: 2004-11-23 22:35
■■XMLの特定のタグの内容を変更するXSLTを作成したいのですが、
  DOCTYPE宣言をコピーする方法がわかりません。
  何か良い方法がないでしょうか?

変換元XMLのタグ<ccccc>の内容を
「いいいいい」から「あいうえお」に変更しようとして、
XSLTを作成しましたが、
DOCTYPE宣言だけがコピーできませんでした。
いろいろ調べましたがDOCTYPE宣言をコピーする方法が
見つけられませんでした。
xsl:outputで公開識別子を出力する方法があると思いますが、
この方法だとまったく同じ内容で出力することができません。
(できないと思っています。特に最後の[]が。)


●変換元XML
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE request PUBLIC "-//SAMPLE//DTD ABCDE 1.0//EN" "abcde.dtd" []>
<?software_name ABC-DEF?>
<?software_version 0123?>
<abcde>
<aaaaa t-name="aaa">あああああ</aaaaa>
<bbbbb t-name="bbb">
<ccccc>いいいいい</ccccc>
</bbbbb>
</abcde>

●XSLT
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="Shift_JIS" />
<xsl:preserve-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ccccc">
<xsl:element name="{name()}">
<xsl:apply-templates select="@*"/>
<xsl:text>あいうえお</xsl:text>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

●出力されるXML
<?xml version="1.0" encoding="Shift_JIS"?>
<?software_name ABC-DEF?>
<?software_version 0123?>
<abcde>
<aaaaa t-name="aaa">あああああ</aaaaa>
<bbbbb t-name="bbb">
<ccccc>あいうえお</ccccc>
</bbbbb>
</abcde>
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2004-11-24 01:23
XSLT1.0 の範囲ではありません、

そういう設計だったから
(XSL−FOの前処理に必要な機能(目次、索引の作成)
しか想定していませんと、仕様の前文に書いてあります。)

軽い仕様を作ったが、意外に汎用に使われて大ヒットなXSLT
なので、不十分さは 各所に出てきます。

[ メッセージ編集済み 編集者: MMX 編集日時 2004-11-24 14:20 ]
バクシ
会議室デビュー日: 2004/10/06
投稿数: 12
投稿日時: 2004-11-24 07:41
XSLTで内部DTDサブセットを生成すること,どうしても必要であれば,テキストとして生成します。XMLのDTDサポートは,SGMLとの互換性のためにあるようなもの,XSLTが内部DTDサブセット生成を命令として提供しないのは,意図的でしょう。

<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE abcde PUBLIC "-//SAMPLE//DTD ABCDE 1.0//EN" "abcde.dtd" [内部dtdサブセット]>]]></xsl:text>

これを<xsl:template match="/">の直下に置きます。ちなみに,サンプルの
<!DOCTYPE request....
おかしくありませんか。
ryu
会議室デビュー日: 2003/02/01
投稿数: 4
投稿日時: 2004-11-24 12:00
ありがとうございます。

テキストとして生成する方法で対応しようと思います。

ただ、この方法の場合、固定文言の出力になりますのでDTDバージョンが変更になって公開識別子が変更された場合に、修正が発生します。
コピーができれば、そのあたりを気にする必要がなくなりますので、より良いのですが、運用を少し考慮すれば対応可能なのでこの方法でいきたいと思います。

ちなみに、サンプルの<!DOCTYPE request....は、ご指摘の通り誤りです。


Kanji
会議室デビュー日: 2004/09/16
投稿数: 5
投稿日時: 2004-11-26 18:44
仮にJavaでDOMを行うのであれば

//XMLファイルよりDoctype宣言取得
Document document = LoaderUtil.loadXMLtoDOM(filename);
DocumentType documentType = document.getDoctype();


TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
//DOCTYPE宣言を追加
transformer.setOutputProperty(OutputKeys.ENCODING, "Shift_JIS" );
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "dtd/pp-schema-config.dtd");

//XMLを変換
transformer.transform(source, result);

Doctype宣言の取得と、ファイルへの出力はできます。
(・・・・出力はベタ打ちしてますが)

参考になれば、幸いです。
1

スキルアップ/キャリアアップ(JOB@IT)