階層の深いXMLに要素を挿入
昨日の夜中、不意打ちをくらった。
突然の落雷。
バリバリ~~って。
いやぁ、ビックリビックリ。
お昼くらいまでは曇りで、午後から太陽がちょっと見えた。
気温はそんなに上がっていなくても、ムッシムッシだね。
僕は、Windowsのソフトウェアを作る時は、VB.NETのVisual Basicを使う。
設定ファイルは、昔からの流れで、INIファイル。
やっぱりINIファイルの方が、見た目はわかりやすいし、直接ファイルを触る時も扱いやすい。
日本語や英語だけの環境であれば、Shift-JISでいいのだけれど、多言語、つまり、ユニコード対応となると、Shift-JISでは出来ない。
UTF-8でいけるか?と思ったけれど、それはダメで、なんとまぁ、「UTF-16LE BOM付き」のテキストファイルである必要性がある。
新しくプログラムを作る時、先人が残してくれたINIファイル読み書きClassを流用する。
ただ、これがちょっと面倒。
随分前から、VB.NETでは、XMLファイルで設定ファイルを作ることを推奨している。
そうすれば、「UTF-8 BOM付き」で扱える。
一度作ってしまえば、UTF-8だろうが、UTF-16LEだろうが、あまり関係ないのだけれど、気分的には、UTF-8の方がいいかな。(笑)
ただ、XMLって、あのタグというのが仰々しいんだよねぇ。
だから、敬遠していた。食わず嫌いだ。(苦笑)
ひょんなことから、XMLファイルを探求してみようと思って、色々とやってみた。
XMLとXSL。それをHTML化にする、とか。
だいたいXMLというものがわかったので、VB.NETでもXMLを扱ってみることにした。
なんとまぁ、わかってしまえば、INIファイルより、読み書きはとても簡単!
(一つ問題点はあるんだけれど、それは今回の件とは関係ないので、割愛。)
いくつかのライブラリーをインポートするだけでいい。INIファイルを読み書きする時の準備より楽だった。
でも、一つだけはまってしまったことがあった。
調べても適当な情報が出てこなかったので、今回は、それについて残しておこうと思う。
何にはまったか?
題名の通り、「階層の深いXMLに要素を挿入」すること。
追加というより、挿入の方が言葉は相応しいかな、と。
設定ファイルとしてXMLを使う場合、そんなに深い階層にはしないので、僕が今回やったことはイレギュラーかもしれないけれど、XMLをデータベースやテーブル的に使う場合は、深い階層にすることもあるかもしれない。
ルート直下に追加するのは簡単だったのだけれど、こういうXMLに要素を挿入するという情報があまりなかったのである。
<?xml version="1.0" encoding="utf-8"?>
<Level1>
<Level2>
<Level3>
<Level4>
<Level5>
<Level6>
<L6child11>kkk</L6child11>
<L6child12>lll</L6child12>
</Level6>
</Level5>
<L4child1>aaa</L4child1>
<L4child2>bbb</L4child2>
</Level4>
</Level3>
</Level2>
</Level1>
こんなの、本当にイレギュラーだ。(苦笑)
ある情報を見ていて、そういうこと?ということに気付いて、問題解決!
そのソースがこれ。
Dim path As String = "xmladd.xml"
Dim xDoc = XElement.Load(path)
'Level4直下に、新たな子を追加
Dim Level4 = xDoc.XPathSelectElement("Level2/Level3/Level4")
Dim Xmlele As XElement =
<L4child3>ccc🦌</L4child3>
Level4.Add(Xmlele)'Level6直下に、新たな子を追加
Dim Level6 = xDoc.XPathSelectElement("Level2/Level3/Level4/Level5/Level6")
Xmlele = New XElement("L6child13", "mmm🚛")
Level6.Add(Xmlele)'Level6直下に、新たなレベルとその子を追加
Xmlele =
<Level7a No="555" Addr="33">
<L7achild1>1</L7achild1>
<L7achild2>2</L7achild2>
</Level7a>
Level6.Add(Xmlele)'Level6直下に、新たなレベルとその子を追加
Dim Num = "88"
Xmlele = New XElement("Level7b",
New XAttribute("No", "777"),
New XAttribute("Addr", Num),
New XElement("L7bchild7a", "sss☑"),
New XElement("L7bchild7b", "ttt🔣")
)
Level6.Add(Xmlele)xDoc.Save(path)
予め、「Imports System.Xml」「Imports System.Xml.XPath」はしておこう。
やっていることは、Level4とLevel6に、要素を追加すること。
結果がこれ。
<?xml version="1.0" encoding="utf-8"?>
<Level1>
<Level2>
<Level3>
<Level4>
<Level5>
<Level6>
<L6child11>kkk</L6child11>
<L6child12>lll</L6child12>
<L6child13>mmm🚛</L6child13>
<Level7a No="555" Addr="33">
<L7achild1>1</L7achild1>
<L7achild2>2</L7achild2>
</Level7a>
<Level7b No="777" Addr="88">
<L7bchild7a>sss☑</L7bchild7a>
<L7bchild7b>ttt🔣</L7bchild7b>
</Level7b>
</Level6>
</Level5>
<L4child1>aaa</L4child1>
<L4child2>bbb</L4child2>
<L4child3>ccc🦌</L4child3>
</Level4>
</Level3>
</Level2>
</Level1>
太字のものが挿入されたもの。絵文字は意味なし。ユニコードなので、入れてみただけ。(笑)
ポイントは、「XPathSelectElement」での指定の仕方。
Level4を例にすると、上記では、
Dim Level4 = xDoc.XPathSelectElement("Level2/Level3/Level4")
と、書いている。
気が付いただろうか?
普通に考えれば、
Dim Level4 = xDoc.XPathSelectElement("/Level1/Level2/Level3/Level4")
にすると思うよね?
つまり、ルートから指定する。
でも、どうやら、ルートは「当たり前」ということらしく、その次の要素から記述するようだ。
これに気付かず、なんでダメなんだ??と余計なことまで調べていたのである。(苦笑)
別に上記の書き方でもOKにしてくれていればいいのに、と思うのは僕だけではないはず。
いや、もしかして、XML的に、そういうルールでもあるのだろうか?
この情報があまりなかったので、残しておこうかな、と思って書いた次第。
いくつか要素を挿入しているけれど、「XElement」で宣言するやり方で、タグそのまま「<L4child3>ccc🦌</L4child3>」のように記述するやり方と、「New XElement("L7bchild7a", "sss☑"),」という形で記述するやり方も書いておいた。
これで、どんなに階層が深くても、どこにでも要素を挿入出来るよ!
| 固定リンク
« 異体字 | トップページ | XMLのコメント »
「パソコン・インターネット」カテゴリの記事
- とうとう来てしまった(2024.12.04)
- 定例のアップデート(2024.11.28)
- 今日はどうだったか(2024.11.22)
- 何かが降ってきた(2024.11.21)
- 画面内の文字をテキスト化(2024.11.19)
コメント