我是VBScript和XML编码的新手。但是,让我了解并尝试理解W3学校和其他在线论坛的概念。
我想使用VBScript读取/解析xml文件,我的XML文件不是数据,而是来自应用程序的xml源代码。
以下是我正在使用的代码段 -
Sub LoadXMLFile()
Dim objXML 'for xml document
Dim objNode 'for xml node item
Dim i As Integer
i = 0
Set objXML = CreateObject("Microsoft.XMLDOM")
objXML.Load ("C:\path\test.xml")
objXML.setProperty "SelectionLanguage", "XPath"
Set objNode = objXML.SelectNodes("/report/queries/query/selection/dataItem/text()")
'MsgBox objNode.Text
For i = 0 To (objNode.Length - 1)
NodeVal = objNode(i).NodeValue
MsgBox NodeVal
Next
End Sub
当我逐步执行VB代码时,objNode.Length值总是计算为0.不确定为什么它不计算长度。
这是我要解析的xml -
<report xmlns="http://developer.cognos.com/schemas/report/10.0/" useStyleVersion="10" expressionLocale="en-us">
<modelPath>
/content/package[@name='GO Sales (query)']/model[@name='model']
</modelPath>
<drillBehavior/>
<queries>
<query name="Query1">
<source>
<model/>
</source>
<selection>
<dataItem aggregate="none" rollupAggregate="none" name="Product line">
<expression>[Sales (query)].[Products].[Product line]</expression>
<XMLAttributes>
<XMLAttribute output="no" name="RS_dataType" value="3"/>
<XMLAttribute output="no" name="RS_dataUsage" value="attribute"/>
</XMLAttributes>
</dataItem>
<dataItem aggregate="none" rollupAggregate="none" name="Product type">
<expression>[Sales (query)].[Products].[Product type]</expression>
<XMLAttributes>
<XMLAttribute output="no" name="RS_dataType" value="3"/>
<XMLAttribute output="no" name="RS_dataUsage" value="attribute"/>
</XMLAttributes>
</dataItem>
</selection>
</query>
</queries>
</report>
感谢您的时间和回应。
谢谢&amp;问候 拉吉
答案 0 :(得分:1)
第一个问题是dataItem
元素没有文本节点作为直接子节点。因此...dataItem/text()
将返回null。
dataItem
元素包含元素节点expression
和XMLAttributes
。 expression
包含文本节点。 XMLAttributes
包含更多子节点。
如果找到dataItem
元素,我们可以迭代所有这些节点。或者我们可以简单地从所有子节点获取所有文本内容。我们可以用{DOM}对象在XML DOM Objects/Interfaces
第二个问题是XML中定义了一个名称空间。这需要XML解析器知道。如果没有,解析器将假定名称空间之外的所有元素,因此它不会找到名称空间内的所有元素。
因此,使用您的XML,您可以执行以下操作:
Sub LoadXMLFile()
Dim objXML 'for xml document
Dim objNodeList 'for xml node lists
Dim objNode 'for xml node
Dim oAttribute 'for xml attribute
Dim oChildNode 'for xml node
Dim oSubChildNode 'for xml node
Set objXML = CreateObject("Microsoft.XMLDOM")
objXML.Load ("C:\Users\Axel Richter\Desktop\test.xml")
objXML.setProperty "SelectionLanguage", "XPath"
objXML.setProperty "SelectionNamespaces", "xmlns:dcc=""http://developer.cognos.com/schemas/report/10.0/"""
Set objNodeList = objXML.SelectNodes("/dcc:report/dcc:queries/dcc:query/dcc:selection/dcc:dataItem")
For Each objNode In objNodeList
MsgBox objNode.Text 'the text content in this element and its child elements
'go through all attributes
For Each oAttribute In objNode.Attributes
MsgBox oAttribute.Name & ": " & oAttribute.Text
Next
'go through all child nodes
For Each oChildNode In objNode.ChildNodes
'if the child node has child b´nodes of its own, go through them too
If oChildNode.HasChildNodes Then
For Each oSubChildNode In oChildNode.ChildNodes
MsgBox oSubChildNode.nodeName & ": " & oSubChildNode.XML
Next
Else
MsgBox oChildNode.nodeName & ": " & oChildNode.Text
End If
Next
Next
End Sub
用
objXML.setProperty "SelectionNamespaces", "xmlns:dcc=""http://developer.cognos.com/schemas/report/10.0/"""
我为命名空间
定义了前缀dcc
http://developer.cognos.com/schemas/report/10.0/
。
dcc
是我自己的选择( d eveloper c ognos c om)。 selectNodes Method中的XPATH正常工作需要此前缀。由于XML中的所有元素都在此命名空间中,因为根元素report
具有此xmlns
属性,因此XPATH需要从此命名空间中选择report
的所有子元素。否则它将无法工作。
因此,XPATH中的所有元素都需要dcc
前缀,这些元素位于此命名空间中。如果存在多个名称空间,则需要多个前缀。每个命名空间一个。
这是XPATH准确的工作条件之一。 getElement...
方法对此命名空间的容忍度更高。但实际上命名空间就在那里,所以它也应该得到尊重。