C#
XmlDocumentで名前空間と接頭辞を追加する
答えにたどりつくまでに苦労したので、メモしておこう。以下、ATOMに名前空間「urn:photo.hesperus.net」と接頭辞「phn」を追加する例。
XmlDocument atomDocument = new XmlDocument();
XmlElement atomEntry = atomDocument.CreateElement("entry", "http://www.w3.org/2005/Atom");
atomDocument.AppendChild(atomEntry);
// ここがポイント。<entry>要素に名前空間と接頭辞を追加する。
XmlAttribute xmlnsPhn = atomDocument.CreateAttribute("xmlns", "phn", "http://www.w3.org/2000/xmlns/");
xmlnsPhn.Value = "urn:photo.hesperus.net";
atomEntry.Attributes.Append(xmlnsPhn);
XmlElement phnProperty = atomDocument.CreateElement("phn", "property", "urn:photo.hesperus.net");
atomEntry.AppendChild(phnProperty);
XmlAttribute propertyName = atomDocument.CreateAttribute("name");
propertyName.Value = "thumbnail";
phnProperty.Attributes.Append(propertyName);
XmlAttribute propertyHref = atomDocument.CreateAttribute("href");
propertyHref.Value = "/img/hoge.jpg";
phnProperty.Attributes.Append(propertyHref);
出力は次のようになる。
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:phn="urn:photo.hesperus.net">
<phn:property name="thumbnail" href="/img/hoge.jpg" />
</entry>
まるで「xmlns」が名前空間「http://www.w3.org/2000/xmlns/」の接頭辞であるかのようだ。この名前空間を知らないと、うまくいかない。参考にしたのは英語のページ。何が書かれているのか、さっぱりわからなかったが、コーディングは理解した。
http://stackoverflow.com/questions/10807173/xmldocument-prefix-not-being-outputted
失敗例:その1
<entry>要素に名前空間「urn:photo.hesperus.net」と接頭辞「phn」を追加しないと、<phn:property>要素に追加されてしまう。
<entry xmlns="http://www.w3.org/2005/Atom">
<phn:property xmlns:phn="urn:photo.hesperus.net" name="thumbnail" href="/img/hoge.jpg" />
</entry>
<phn:property>要素がひとつだけなら、そもそも接頭辞を使うまでもない。
<entry xmlns="http://www.w3.org/2005/Atom">
<property xmlns="urn:photo.hesperus.net" name="thumbnail" href="/img/hoge.jpg" />
</entry>
だが、<phn:property>要素が複数あったり、接頭辞「phn」を使う他の要素があったりすると、合理性を欠くことになる。
<entry xmlns="http://www.w3.org/2005/Atom">
<phn:property xmlns:phn="urn:photo.hesperus.net" name="thumbnail" href="/img/hoge.jpg" />
<phn:property xmlns:phn="urn:photo.hesperus.net" name="date" value="2016-04-13" />
<phn:property xmlns:phn="urn:photo.hesperus.net" name="place" value="tokyo" />
<phn:info xmlns:phn="urn:photo.hesperus.net">thanks: everyone</phn:info>
</entry>
これは避けたい。接頭辞を使わなくても、ちょっと納得いかない感じだ。
<entry xmlns="http://www.w3.org/2005/Atom">
<property xmlns="urn:photo.hesperus.net" name="thumbnail" href="/img/hoge.jpg" />
<property xmlns="urn:photo.hesperus.net" name="date" value="2016-04-13" />
<property xmlns="urn:photo.hesperus.net" name="place" value="tokyo" />
<info xmlns="urn:photo.hesperus.net">thanks: everyone</info>
</entry>
失敗例:その2
形から察すると「xmlns」は接頭辞、「phn」はローカル名、「urn:photo.hesperus.net」は値に見えるので、何となくそんな感じでやってみた。
XmlElement xmlnsPhn = atomDocument.CreateAttribute("xmlns", "phn", "urn:photo.hesperus.net");
atomEntry.Attributes.Append(xmlnsPhn);
CreateAttribute()のところでエラー。名前空間がどうこうとか意味不明のことを言われる。よく見れば、やってることも意味不明だったが、結果的には正解に近かったな。
失敗例:その3
<entry>要素にダミーの属性を追加するとマシになるが、出力されたものを見れば、やはりダミーの属性は無駄だと思う。接頭辞の定義だけで良い。
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:phn="urn:photo.hesperus.net" phn:dummyAttribute="dummyValue">
<phn:property name="thumbnail" href="/img/hoge.jpg" />
</entry>
追記
混乱をきたさないように追記しておくと、ATOMのルート要素は<feed>と<entry>のどちらでも良い。RSSで使われるのは、ルート要素が<feed>のATOM。ルート要素が<entry>のATOMは、あまり見られない。
(2016/04/14 初稿)