XMLデータで複数の条件でデータを抽出するには?

解決


あらさん  2008-08-23 01:55:17  No: 145120

こんにちは。
下記のようなXMLデータがあり、その中から日付が8/20〜8/22にあてはまる
Aの要素を抽出したいのですが、どのようにすればよいのでしょうか。
○〜○日ではなく、○日より先であれば、下記のようにselectnodesを
使用して抽出することができました。
ただ複数となると、ネットで色々調べたのですが、よく分かりませんで
した。
いい方法があれば教えて頂けないでしょうか。

-----------、○日より先を検索した場合----------
Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument
Dim nodelist As System.Xml.XmlNodeList
doc.Load(DataSetPath())
nodelist = doc.SelectNodes("NewDataSet/A[日付>='2008/08/22']")

-------XMLデータ----------

<NewDataSet>
  <A>
    <日付>2008/08/20</日付>
    <test>test1</test>
  </A>
  <A>
    <日付>2008/08/21</日付>
    <test>test2</test>
  </A>
  <A>
    <日付>2008/08/22</日付>
    <test>test3</test>
  </A>
  <A>
    <日付>2008/08/23</日付>
    <test>test4</test>
  </A>
</NewDataSet>


魔界の仮面弁士  2008-08-23 03:05:40  No: 145121

Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument
Dim nodelist As System.Xml.XmlNodeList
doc.Load(DataSetPath())
nodelist = doc.SelectNodes("NewDataSet/A[日付>='2008/08/22']")

XPath 1.0 では、文字列の大小比較は基本的にできません。完全一致のみです。

今回のような [node-set] >= [string] の場合、比較前に数値に変換されるため、
非数値(NaN)となってしまい、期待する結果とはなりません。

なので今回の場合は、
  (1) substring 関数で、年月日単位で分割して
  (2) それぞれを concat 関数で文字列連結して
  (3) それを number 関数で数値に変換して
  (4) これでようやく比較できる状態
といった感じで対処する事になるかと。

nodelist = doc.SelectNodes("NewDataSet/A[number(concat(substring(日付,1,4),substring(日付,6,2),substring(日付,9)))>=20080822]")


魔界の仮面弁士  2008-08-23 03:15:15  No: 145122

> 複数となると

複数の条件があるなら、「or 演算子」「and 演算子」で。

nodelist = doc.SelectNodes("NewDataSet/A[日付='2008/08/22' or 日付='2008/08/23']")

nodelist = doc.SelectNodes("NewDataSet/A[日付='2008/08/22' and test='test3']")
nodelist = doc.SelectNodes("NewDataSet/A[日付='2008/08/22'][test='test3']")


あらさん  2008-08-23 03:39:29  No: 145123

> XPath 1.0 では、文字列の大小比較は基本的にできません。完全一致のみです。
魔界の仮面弁士さんありがとうございます。
完全一致のみということを知りませんでした。
では、『>=2008/08/20 and <=2008/08/22』を抽出する方法は
ないのでしょうか。


魔界の仮面弁士  2008-08-23 10:22:25  No: 145124

> 完全一致のみということを知りませんでした。
ひとつ分からない点があります。

最初の質問で
>>>> ○日より先であれば、下記のようにselectnodesを
>>>> 使用して抽出することができました。
と書かれていましたが、提示されたサンプルでは、ノードが
抽出されなかったようなのですが…。

> 『>=2008/08/20 and <=2008/08/22』を抽出する方法
先の「数値化」による比較を使えば、
  [数値>=20080820 and 数値<=20080822]
という評価式に変換できますよね。

日付のような場合は、まだ数値化できるので対処できますが、
数値化できないような文字列の場合は、XPath ではなく DOM 側で
処理するとか、あるいは、<msxsl:script> の XSLT を介して
処理するなどといった対処になるかと思います。


あらさん  2008-08-25 22:44:58  No: 145125

>>>>> ○日より先であれば、下記のようにselectnodesを
>>>>> 使用して抽出することができました。
>と書かれていましたが、提示されたサンプルでは、ノードが
>抽出されなかったようなのですが…。
ん?と思い、自分でも試してみましたが、抽出できません
でした・・・。
たぶん、ここに質問する前に色々とやっている中で抽出できたような気が
していたのですが、勘違いのようです。
すいません。

>[数値>=20080820 and 数値<=20080822]
試してみます。
抽出できたら、それをXMLに書き出そうと思っています。
これで少し進んだ気がします。
ありがとうございます。


あらさん  2008-08-26 18:20:54  No: 145126

すいません。解決にチェック入れ忘れていました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加