質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

Q&A

解決済

1回答

2709閲覧

【VBA+MSXML2】XPathのcontains関数でワイルドカード指定すると想定の動きをしない

310uk

総合スコア13

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

0グッド

0クリップ

投稿2021/11/17 08:48

編集2021/11/18 01:43

Excel2016のVBAで、XMLを使った処理をしています。

例えば、以下のようなXMLファイル(UTF-8で保存)を用意して、

XML

1<?xml version="1.0" encoding="UTF-8"?> 2<組織> 3 <ユーザ class="cls" id="AAA" 名前="やまだ たろう"/> 4 <ユーザ class="cls" id="BBB" 名前="さとう じろう"/> 5</組織>

VBAで読み込みます。
※とりあえずモジュールで。あくまでサンプルなので細かい書き方は無視してください。

VB

1Dim dom As New MSXML2.DOMDocument 2’以下試しましたが全部同じでした 3'DOMDocument 4'DOMDocument26 5'DOMDocument30 6'DOMDocument60 7 8Sub Test() 9 dom.Load "C:\前述の\XMLファイル.xml" 10 dom.setProperty "SelectionLanguage", "XPath" 11End Sub 12

この後、読み込んだXMLの検索を実装するために以下のような関数を用意したところ、
1バイト文字は正常に動くのに2バイト文字だと検索に引っ掛かりません。

VB

1Sub Search(Text As String) 2 Dim nl As IXMLDOMNodeList 3 4 'XPathのcontains関数で、指定のキーワードを含む属性を持つノードを検索 5 Set nl = dom.SelectNodes("//*[contains(@*, '" & Text & "')]") 6 7 MsgBox nl.Length & "件見つかりました!!" 8End Sub 9 10 11Call Search("AA") ’⇒「1件見つかりました!!」 12Call Search("ろう") ’⇒「0件見つかりました!!」 ※期待値は2件見つかる 13

属性を「@*」でワイルドカード指定しているにもかかわらず、ノードの最初の属性しか見に行かないような動きになります。

どなたか解決方法ご存じの方いらっしゃいましたらご教授お願いいたします。
「それ無理なんだよねー!!」と言う情報でも構いません。その情報ソースをご教示いただけると助かります

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cx20

2021/11/17 13:35

もしかして id の方を探しに行ってないですか? "AAA"→"やまだ たろう" "BBB"→"さとう じろう" に変えてみたらヒットしませんか?
310uk

2021/11/17 13:45

タグ名も属性名もワイルドカードで指定しているので、想定では全属性見ていると思ってますが違うんですかね… 明日確認してみます。 ※違うワイルドカードの指定方法もあるみたいなのでそっちも確認してみます
cx20

2021/11/17 13:51

とりあえず、ローカルで "AAA"→"やまだ たろう" "BBB"→"さとう じろう" に変えてみたところヒットするのは確認しました。 また、以下のように変えた場合は、"ろう" でヒットすることを確認しました。 変更前)"//*[contains(@*, '" 変更後)"//*[contains(@名前, '" XPath についてあまり詳しくないですが、なんとなく「@*」だと先頭の属性しか見ていないような感じでした。
310uk

2021/11/17 14:16

なるほど!ありがとうございます!! 属性を[contains(., 'hoge')]と指定する方法もあると聞いたので、明日調べてみます。
cx20

2021/11/17 14:22

> 属性を[contains(., 'hoge')] それも試してみたのですが、残念ながら、テキストノードを検索する書き方のようでした。。
310uk

2021/11/17 14:24

残念… ありがとうございます!
cx20

2021/11/17 14:50 編集

んー、XPath の仕様が良く分からなくなってきました。 こちらにあったサンプルだと、属性名のワイルドカードは「@*」でやってますね。 VBA+MSXML2 だと全角半角関係なく先頭の属性値しかヒットしないので理由が良く分からず・・(PythonとXPathの扱いが違う?) https://ai-inter1.com/xpath/ > 4.2. 任意の属性を取得(ワイルドカード):*(アスタリスク) >    検索対象)<a class="book" id="link1" href="xxx">Python3</a> >    XPath)//a[@*="link1"]
310uk

2021/11/17 23:15

ホントですね、ありがとうございます。 一点、ソースに記載漏れがありました。 xmldoc.setProperty "SelectionLanguage", "XPath" で明示的にXPath指定してます。
310uk

2021/11/17 23:42

完全一致なら動きますね…contains関数の問題か… dom.SelectNodes("//*[@*='" & Text & "']")
cx20

2021/11/18 00:01

なるほど。。
310uk

2021/11/18 00:08

contains関数だけではなく、 concatやstarts-withも@*でダメでした。 ちなみに、実際のプログラムで扱っているデータは最初の属性がidではないので、最初の属性ではなくidを見ちゃってる可能性がありますね。
cx20

2021/11/18 00:20

やはり "id" ではなく最初の属性を見に行っているっぽいですね。 <ユーザ class="cls" id="AAA" 名前="やまだ たろう"/> だと class の内容を見に行っているようでした。
310uk

2021/11/18 01:14

あら、こちらの環境と動き違いますね。 謎だ…
310uk

2021/11/18 01:42

ごめんなさい、分かりました。 確かに仰られる通り、最初の属性を見ていますね。 実際に使用しているデータでちょっと混乱してしまいました。
310uk

2021/11/18 02:14

仕様だというご回答をいただきました。 一緒に調べていただいてありがとうございました!!
cx20

2021/11/18 03:04

こちらこそ、色々と知見を得られて良かったです。今後の参考にしたいと思います。
guest

回答1

0

ベストアンサー

@* はすべての属性を選択しますが、contains(@*, ...) と書いた場合は ノードセットの文字列化が行われ、仕様で「文書中の最初のノードのテキスト値」が結果になります。

MSXML2がどういうバージョンの XPath 仕様に準拠しているのか知りませんが、XPath 1.0 の範囲内では実現不可能だと思います。

投稿2021/11/18 02:08

int32_t

総合スコア20882

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

310uk

2021/11/18 02:12

そういう仕様なんですね(汗) matche関数が使えなかったので、MSXMLのXPathは1.0だと思います。 部分一致は諦めて、完全一致で実装しようと思います。 ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問