如何使用VBScript读取XML文件?

如何使用VBScript读取XML文件?,xml,vbscript,Xml,Vbscript,早上好 我希望有人能帮助我。我试图在一个xml文件中循环,一边读取值。最后,我需要做的是找到一组特定的信息并从中提取一段信息。我知道这有点混乱,所以让我澄清一下 这是我的xml文件的一个示例 <?xml version="1.0"?> <menu> <header> <listname>Nintendo GameCube</listname> <lastlistupdate>09/26/2017</

早上好

我希望有人能帮助我。我试图在一个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>
读取游戏名是可行的,但游戏等级始终为空。所以我的第一个问题是,我需要改变什么来获得游戏等级

其次,可能更有效的方法是以某种方式更改代码,使其表示我希望看到name=“007-代理受到攻击(美国)”的游戏评级。那代码看起来怎么样

非常感谢您的帮助。

试试这段代码

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
读取游戏名是可行的,但游戏等级始终为空。所以我的第一个问题是,我需要改变什么来获得游戏等级

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

外部资源-

其次,可能更有效的方法是以某种方式更改代码,使其表示我希望看到name=“007-代理受到攻击(美国)”的游戏评级。那代码看起来怎么样

我的方法再次与我对问题1所做的非常相似,但是现在您需要过滤节点,您必须调整xpath以仅选择所需的节点
/menu/game[@name='007-Agent Under Fire(USA)]/rating
-xpath将只匹配那些包含给定值的
name
属性的
game
节点。同样,我将直接转到ratings节点并遍历回它的父节点。

请尝试以下代码

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
读取游戏名是可行的,但游戏等级始终为空。所以我的第一个问题是,我需要改变什么来获得游戏等级

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

外部资源-

其次,可能更有效的方法是以某种方式更改代码,使其表示我希望看到name=“007-代理受到攻击(美国)”的游戏评级。那代码看起来怎么样


我的方法再次与我对问题1所做的非常相似,但是现在您需要过滤节点,您必须调整xpath以仅选择所需的节点
/menu/game[@name='007-Agent Under Fire(USA)]/rating
-xpath将只匹配那些包含给定值的
name
属性的
game
节点。同样,我将直接转到ratings节点并遍历回其父节点。

您非常接近,因为ratings位于子节点的文本中,而不是属性中,您需要的1行修复是:

GameRating = Games.selectSingleNode("rating").text
但是,我对您的脚本有其他问题:

  • 您应该添加
    选项Explicit
    ,以帮助识别任何打字错误
  • 您应该将
    Games
    重命名为
    Games
    ,因为这更好地反映了它对应的XML节点
  • 您应该将
    GroupName
    重命名为
    Menu
    ,因为这样可以更好地匹配XML内容(实际上,您根本不需要这个)
  • 您应该在XPath中使用
    “/menu”
    而不是
    “//menu”
    ,因为您希望它与顶级节点匹配,而且,实际上,由于只有一个顶级节点,您应该使用
    选择单节点
    文档元素
    而不是
    选择节点
  • 事实上,我们可以将
    菜单
    XPath与
    游戏
    XPath与
    /menu/game
    结合起来,一次完成,这就是为什么我们不需要
    组名
  • 我看不到
    plot
    变量的用途,所以我删除了它
以下是所有更改:

Dim xmlDoc, Game, GameName, GameRating

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

For Each Game In xmlDoc.SelectNodes("/menu/game")
REM For Each Game In xmlDoc.SelectNodes("/menu/game[@name='007 - Agent Under Fire (USA)']")
    GameName = Game.getAttribute("name")
    GameRating = Game.selectSingleNode("rating").text

    MsgBox GameName & " ------- " & GameRating
Next
为了回答您的第二部分,我们修改SelectNodes行以包含一个XPath查询来选择您想要的名称。i、 e

REM For Each Game In xmlDoc.SelectNodes("/menu/game")
For Each Game In xmlDoc.SelectNodes("/menu/game[@name='007 - Agent Under Fire (USA)']")
    GameName = Game.getAttribute("name")
    GameRating = Game.selectSingleNode("rating").text

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

您非常接近,因为评级是在子节点的文本中,而不是在属性中,所以您需要的1行修复是:

GameRating = Games.selectSingleNode("rating").text
但是,我对您的脚本有其他问题:

  • 您应该添加
    选项Explicit
    ,以帮助识别任何打字错误
  • 您应该将
    Games
    重命名为
    Games
    ,因为这更好地反映了它对应的XML节点
  • 您应该将
    GroupName
    重命名为
    Menu
    ,因为这样可以更好地匹配XML内容(实际上,您根本不需要这个)
  • 您应该在XPath中使用
    “/menu”
    而不是
    “//menu”
    ,因为您希望它与顶级节点匹配,而且,实际上,由于只有一个顶级节点,您应该使用
    选择单节点
    文档元素
    而不是
    选择节点
  • 事实上,我们可以将
    菜单
    XPath与
    游戏
    XPath与
    /menu/game
    结合起来,一次完成,这就是为什么我们不需要
    组名
  • 我看不到
    plot
    变量的用途,所以我删除了它
以下是所有更改:

Dim xmlDoc, Game, GameName, GameRating

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

For Each Game In xmlDoc.SelectNodes("/menu/game")
REM For Each Game In xmlDoc.SelectNodes("/menu/game[@name='007 - Agent Under Fire (USA)']")
    GameName = Game.getAttribute("name")
    GameRating = Game.selectSingleNode("rating").text

    MsgBox GameName & " ------- " & GameRating
Next
为了回答您的第二部分,我们修改SelectNodes行以包含一个XPath查询来选择您想要的名称。i、 e

REM For Each Game In xmlDoc.SelectNodes("/menu/game")
For Each Game In xmlDoc.SelectNodes("/menu/game[@name='007 - Agent Under Fire (USA)']")
    GameName = Game.getAttribute("name")
    GameRating = Game.selectSingleNode("rating").text

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

您发布的解决方案没有问题,但您没有努力解释