- PR -

C#でのXML操作について

1
投稿者投稿内容
ごっつ
会議室デビュー日: 2005/08/01
投稿数: 18
投稿日時: 2005-08-08 20:02
いつもお世話になっております。
今回はC#でのXML操作について、特にprefixの指定について教えてください!
現在C#でXMLを操作しているのですが、prefixを指定しても、
反映されず困っております。例えば、

Element outputRoot = outputDocument.CreateElement("lib:test");
と指定しても、XMLのタグでは<test>...</test>としかならず、カンマより
前の文字列(prefix指定)が反映されません。

ただ、
Element outputRoot = outputDocument.CreateElement("lib","test","dummy");
と指定すれば、<lib:test xmlns:lib="dummy">のようなタグが表示されますが、
「xmlns:lib="xmlns"」の部分は要らないのです。

最終的にはどうにか
<lib:test>....</lib:test>
のような形で指定できればと思っています。

C#もXMLも本当に基本的なことしか分かっておらず、
ご迷惑をお掛けしますが、解決策をご存知の方がいらっしゃいましたら、
教えてください。お願い致します!!
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-08-08 23:44
>「xmlns:lib="xmlns"」の部分は要らないのです。
xml仕様では、欠かせません。要ります
ごっつ
会議室デビュー日: 2005/08/01
投稿数: 18
投稿日時: 2005-08-09 08:47
>>「xmlns:lib="xmlns"」の部分は要らないのです。
>xml仕様では、欠かせません。要ります

だとしても、なぜ
>Element outputRoot = outputDocument.CreateElement("lib:test");
で<lib:test/>にならないのかが分かりません。
教えてください。
にしざき
ぬし
会議室デビュー日: 2003/06/30
投稿数: 304
投稿日時: 2005-08-09 09:04
> なぜ
まさに namespace が指定されていないからでしょう。
ごっつ
会議室デビュー日: 2005/08/01
投稿数: 18
投稿日時: 2005-08-09 10:16
お世話になっております。
にしざきさんのご指摘通り修正したところ、
無事解決しました。

初歩的な質問にお答え頂き、有難うございました。
Atsushi.Eno
ベテラン
会議室デビュー日: 2003/04/23
投稿数: 60
投稿日時: 2005-08-09 12:09
引用:

xml仕様では、欠かせません。要ります



欠かせます。要りません。Namespaces in XMLはXML 1.xの必要条件ではありません。

引用:

だとしても、なぜ
>Element outputRoot = outputDocument.CreateElement("lib:test");
で<lib:test/>にならないのかが分かりません。


Microsoftが.NETのDOMサポートの設計に失敗したためです。

CreateElement()で指定された名前は、名前空間指定の無いローカル名でなければならないところ、XmlDocumentでは単なるCreateElement(name,namespaceURI)のオーバーロード扱いになっているため、"lib"はプレフィックスという扱いになってしまうのです。

XmlElementは(W3C標準のDOMは、ではありません)、NamespaceURIがString.Emptyである場合には、WriteTo()で出力してもプレフィックスが出力されません(そのようなXMLはNamespace in XMLに違反してしまうので、XmlWriterが拒絶する可能性があります。少なくともXmlTextWriterはNamespaceURIがString.Emptyである場合、String.EmptyではないPrefixを拒絶します)。

が…面白いことに、XmlTextReaderでNamespacesプロパティにfalseを指定した場合、XmlDocumentでこれをLoad()すると、LocalNameが"lib:test"であるようなXmlElementが生成され、Save()ではxmlnsを伴わずに出力されます(XmlTextWriterはNamespaceURIがnull(String.Emptyとは異なる)場合、Namespaces in XMLを考慮しません)。

DocumentBuilderFactoryのsetFeature()みたいなのをサポートするだけでも良かったはずなんですけどね。

本題のxmlnsを削りたいという点については、僕なら、XmlTextWriterをラップする出力用のXmlWriterを自作して、WriteStartElement()とWriteStartAttribute()が来たときに、PrefixとLocalNameを":"を挟んで繋げたnameとnull namespaceURIで出力し、WriteStartAttribute()にnamespaceURIが http://www.w3.org/2000/xmlns/ であるようなノードが来た場合は次のWriteEndAttribute()までダミーのXmlWriter(TextWriter.Nullでも使う)を出力先にすげ替えます(これをしないとWriteString()などは呼ばれてしまうので)。まあめんどくさいですね。忘れてください(笑
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-08-09 16:35
>欠かせます。要りません。Namespaces in XMLはXML 1.xの必要条件ではありません。
たしかに。
Well-formed, DTD の検証では Valid です
XML Schema の検証では 要ります
1

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