如何使用VBScript读取XML文件?

时间:2018-02-15 16:42:25

标签: xml vbscript

早上好,

我希望有人可以帮助我。我正在尝试循环读取值的xml文件。最后,我需要做的是找到一组特定的信息并从中提取一条信息。我知道这有点令人困惑,所以让我澄清一下。

以下是我的xml文件示例。

<?xml version="1.0"?>
<menu>
  <header>
    <listname>Nintendo GameCube</listname>
    <lastlistupdate>09/26/2017</lastlistupdate>
    <listversion>SupraKarma1.1</listversion>
  </header>
  <game name="007 - Agent Under Fire (USA)" index="true" image="0">
    <description>007: Agent Under Fire (USA)</description>
    <cloneof />
    <crc />
    <manufacturer>EA Games</manufacturer>
    <year>2002</year>
    <genre>Action</genre>
    <rating>ESRB - T (Teen)</rating>
    <enabled>Yes</enabled>
  </game>
  <game name="007 - Everything or Nothing (USA)" index="" image="">
    <description>007: Everything or Nothing (USA)</description>
    <cloneof />
    <crc />
    <manufacturer>EA Games</manufacturer>
    <year>2004</year>
    <genre>Action</genre>
    <rating>ESRB - T (Teen)</rating>
    <enabled>Yes</enabled>
  </game>
</menu>

以下是我目前要循环读取数据的内容。

Dim xmlDoc, GroupName, Games
Dim plot, GameName, GameRating

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.load("C:\test.xml")`enter code here`

plot="No Value"

For Each GroupName In xmlDoc.SelectNodes("//menu")


    For Each Games In GroupName.SelectNodes("./game")
        GameName = Games.getAttribute("name")
        GameRating = Games.getAttribute("rating")

        MsgBox GameName & " ------- " & GameRating
    Next
Next

正在努力阅读GameName,但GameRating始终为空白。所以我的第一个问题是我需要改变什么来获得GameRating?

其次,以某种方式更改代码以表示我希望看到名称=“007 - Agent Under Fire(USA)”的游戏评级可能更有效。那段代码看起来怎么样?

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

试试此代码

Set objXML = CreateObject("MSXML2.DOMDocument.6.0")
With objXML
    .SetProperty "SelectionLanguage", "XPath"
    .ValidateOnParse = True
    .Async = False
    .Load "C:\Users\pankaj.jaju\Desktop\test.xml"
End With

'Possible solution to Question 1
Set objNodes = objXML.SelectNodes("/menu/game/rating")
For Each objNode In objNodes
    MsgBox "Game Name = " & objNode.ParentNode.GetAttribute("name") & vbCrLf & "Game Rating = " & objNode.Text
Next

'Possible solution to Question 2
Set objNodes = objXML.SelectNodes("/menu/game[@name='007 - Agent Under Fire (USA)']/rating")
For Each objNode In objNodes
    MsgBox "Game Name = " & objNode.ParentNode.GetAttribute("name") & vbCrLf & "Game Rating = " & objNode.Text
Next

正在努力阅读GameName,但GameRating始终为空白。所以我的第一个问题是我需要更改什么才能获得GameRating?

您的代码正在尝试查找rating元素的game属性,该属性不正确。与name不同,rating也是一个元素(game的子项),而不是game的属性。我的解决方案基本上是找到rating节点(因为你主要对这些节点感兴趣),然后遍历回其父节点(game)以提取游戏名称信息。

外部资源 - https://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp

其次,以某种方式更改代码以表示我希望看到名称=“007 - Agent Under Fire(USA)”的游戏评级可能更有效。那段代码看起来如何?

我的方法与我在问题1中所做的非常类似,但是现在您想要过滤节点,您必须调整xpath以仅选择所需的节点。 /menu/game[@name='007 - Agent Under Fire (USA)']/rating - xpath将仅匹配包含给定值的game属性的name个节点。我再次直接进入评级节点并遍历其父节点。

答案 1 :(得分:1)

你非常接近,因为,评级是在子节点的文本中,而不是属性,你需要的1个线程修复:

GameRating = Games.selectSingleNode("rating").text

但是,我的脚本还有其他问题:

  • 您应该添加Option Explicit以帮助解决任何拼写错误
  • 您应该将Games重命名为Game,因为这反映了它更符合的XML节点
  • 您应该将GroupName重命名为Menu,因为它更符合XML内容(事实上,您根本不需要此内容)
  • 您应该在XPath中使用"/menu"而不是"//menu",因为您希望它与顶级节点匹配,事实上,因为只有1个顶级节点,所以您应该使用{{ 1}}或selectSingleNode代替documentElement
  • 事实上,我们可以将您的selectNodes XPath与menu XPath与game结合使用,并在一次性完成这两项操作,这就是为什么我们不需要{{ 1}}
  • 我看不到/menu/game变量的用途,所以,我删除了它

以下是所有更改:

GroupName

要回答第二部分,我们修改SelectNodes行以包含XPath查询以选择所需的名称。即

plot