早上好,
我希望有人可以帮助我。我正在尝试循环读取值的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)”的游戏评级可能更有效。那段代码看起来怎么样?
非常感谢您的帮助。
答案 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内容(事实上,您根本不需要此内容)"/menu"
而不是"//menu"
,因为您希望它与顶级节点匹配,事实上,因为只有1个顶级节点,所以您应该使用{{ 1}}或selectSingleNode
代替documentElement
。selectNodes
XPath与menu
XPath与game
结合使用,并在一次性完成这两项操作,这就是为什么我们不需要{{ 1}} /menu/game
变量的用途,所以,我删除了它以下是所有更改:
GroupName
要回答第二部分,我们修改SelectNodes行以包含XPath查询以选择所需的名称。即
plot