Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml VBA DOM父节点选择单节点_Xml_Vba_Dom_Xpath_Xml Parsing - Fatal编程技术网

Xml VBA DOM父节点选择单节点

Xml VBA DOM父节点选择单节点,xml,vba,dom,xpath,xml-parsing,Xml,Vba,Dom,Xpath,Xml Parsing,我在这行代码中不断遇到对象错误,我不明白为什么: Sub mySub() Dim XMLFile As Variant Dim Author As Variant Dim athr As String, BookType As String, Title As String Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As String Dim i As Long, x As Long, j As

我在这行代码中不断遇到对象错误,我不明白为什么:

Sub mySub()

Dim XMLFile As Variant
Dim Author As Variant
Dim athr As String, BookType As String, Title As String
Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As  String
Dim i As Long, x As Long, j As Long

Dim mainWorkBook As Workbook
Dim n As IXMLDOMNode
Set mainWorkBook = ActiveWorkbook
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("C:\Books.xml")


x = 1
j = 0

Set Author = XMLFile.SelectNodes("/catalog/book/author/text()")
For i = 0 To (Author.Length - 1)
    ReDim Preserve AuthorArray(0 To i)
    ReDim Preserve BookTypeArray(0 To i)
    ReDim Preserve TitleArray(0 To i)
    athr = Author(i).NodeValue
    BookType = Author(i).ParentNode.ParentNode.getAttribute("id")
    Title = Author(i).ParentNode.SelectSingleNode("title")

    If athr = "Ralls, Kim" Then

        AuthorArray(j) = athr
        BookTypeArray(j) = BookType
        TitleArray(j) = Title

        j = j + 1
        x = x + 1
    End If
Next



Range("A3:A" & UBound(AuthorArray) + 1) = WorksheetFunction.Transpose(AuthorArray)
Range("B3:B" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(BookTypeArray)
Range("C3:C" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(TitleArray)


End Sub

感谢您的帮助和建议。

不熟悉VBA,但很可能是因为这行代码导致您出错

Title = Author(i).ParentNode.SelectSingleNode("title")
Author
变量(?)设置为字符串值,
text()
表示作为上下文元素直接子元素的所有文本节点的串联。字符串与元素非常不同,它们没有属性或子元素

它们确实有一个父节点,但是

Set Author = XMLFile.SelectNodes("/catalog/book/author/text()")
将尝试检索这样一个文本节点的父节点的
id
属性,它是
author
元素-但是
author
元素没有
id
属性

改变

BookType = Author(i).ParentNode.getAttribute("id")

如果有帮助,请告诉我


编辑:我想我找到了一个可行的解决方案,下面如何。然而,我完全不熟悉VBA-我相信这不是一个非常优雅的解决方案,可以改进很多

Set Author = XMLFile.SelectNodes("/catalog/book/author")
结果

Sub mySub()

Dim XMLFile As MSXML2.DOMDocument
Dim Author As Variant
Dim athr As String, BookType As String, Title As String
Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As String
Dim i As Long, x As Long, j As Long

Dim mainWorkBook As Workbook
Dim n As IXMLDOMNode
Set mainWorkBook = ActiveWorkbook
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("vba.xml")


x = 1
j = 0

Set Author = XMLFile.SelectNodes("/catalog/book/author")
For i = 0 To (Author.Length - 1)
    ReDim Preserve AuthorArray(0 To i)
    ReDim Preserve BookTypeArray(0 To i)
    ReDim Preserve TitleArray(0 To i)
    athr = Author(i).Text
    BookType = Author(i).ParentNode.getAttribute("id")
    Title = Author(i).ParentNode.getElementsByTagName("title").Item(0).nodeTypedValue

    If athr = "Ralls, Kim" Then

        AuthorArray(j) = athr
        BookTypeArray(j) = BookType
        TitleArray(j) = Title

        j = j + 1
        x = x + 1
    End If
Next



Range("A3:A" & UBound(AuthorArray) + 1) = WorksheetFunction.Transpose(AuthorArray)
Range("B3:B" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(BookTypeArray)
Range("C3:C" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(TitleArray)


End Sub

第二次编辑

您能否解释一下项(0)在此行中的作用
Title=Author(i).ParentNode.getElementsByTagName(“Title”).Item(0).nodeTypedValue

getElementsByTagName()
返回元素的集合,即使只有一个结果,它也会在只有一个项的集合中结束<代码>项(0)选择此集合中的第一个元素

然后,根据对象的数据类型返回对象的值。顺便说一下,
NodeValue
属性-这就是代码返回错误的原因

此外,是否需要在节点的XPath中使用/text()(它似乎也不会影响数字或任何东西)

(最后一点我很满意!我想您可以从XPath的介绍或教程中获益。)

text()
是一个被过度使用的结构,但确实有它的用途。这样想:当XML读入内存时,就会构造一个树状表示。在这种表示法中,所有类型的对象都是节点;元素是节点,属性是节点,文本内容是节点

现在,一个XPath表达式

Ralls, Kim  Adventure   Midnight Rain
Ralls, Kim  Mystery     Some Mystery Book
选择一个元素节点(或者,可能是一组元素节点)。在您的例子中,它是一个元素节点,其子节点是文本节点。将路径表达式扩展到

/catalog/book/author

仅选择
author
元素的子文本节点。理解元素及其文本内容不相同很重要。

不熟悉VBA,但很可能是因为这一行

Title = Author(i).ParentNode.SelectSingleNode("title")
Author
变量(?)设置为字符串值,
text()
表示作为上下文元素直接子元素的所有文本节点的串联。字符串与元素非常不同,它们没有属性或子元素

它们确实有一个父节点,但是

Set Author = XMLFile.SelectNodes("/catalog/book/author/text()")
将尝试检索这样一个文本节点的父节点的
id
属性,它是
author
元素-但是
author
元素没有
id
属性

改变

BookType = Author(i).ParentNode.getAttribute("id")

如果有帮助,请告诉我


编辑:我想我找到了一个可行的解决方案,下面如何。然而,我完全不熟悉VBA-我相信这不是一个非常优雅的解决方案,可以改进很多

Set Author = XMLFile.SelectNodes("/catalog/book/author")
结果

Sub mySub()

Dim XMLFile As MSXML2.DOMDocument
Dim Author As Variant
Dim athr As String, BookType As String, Title As String
Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As String
Dim i As Long, x As Long, j As Long

Dim mainWorkBook As Workbook
Dim n As IXMLDOMNode
Set mainWorkBook = ActiveWorkbook
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("vba.xml")


x = 1
j = 0

Set Author = XMLFile.SelectNodes("/catalog/book/author")
For i = 0 To (Author.Length - 1)
    ReDim Preserve AuthorArray(0 To i)
    ReDim Preserve BookTypeArray(0 To i)
    ReDim Preserve TitleArray(0 To i)
    athr = Author(i).Text
    BookType = Author(i).ParentNode.getAttribute("id")
    Title = Author(i).ParentNode.getElementsByTagName("title").Item(0).nodeTypedValue

    If athr = "Ralls, Kim" Then

        AuthorArray(j) = athr
        BookTypeArray(j) = BookType
        TitleArray(j) = Title

        j = j + 1
        x = x + 1
    End If
Next



Range("A3:A" & UBound(AuthorArray) + 1) = WorksheetFunction.Transpose(AuthorArray)
Range("B3:B" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(BookTypeArray)
Range("C3:C" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(TitleArray)


End Sub

第二次编辑

您能否解释一下项(0)在此行中的作用
Title=Author(i).ParentNode.getElementsByTagName(“Title”).Item(0).nodeTypedValue

getElementsByTagName()
返回元素的集合,即使只有一个结果,它也会在只有一个项的集合中结束<代码>项(0)选择此集合中的第一个元素

然后,根据对象的数据类型返回对象的值。顺便说一下,
NodeValue
属性-这就是代码返回错误的原因

此外,是否需要在节点的XPath中使用/text()(它似乎也不会影响数字或任何东西)

(最后一点我很满意!我想您可以从XPath的介绍或教程中获益。)

text()
是一个被过度使用的结构,但确实有它的用途。这样想:当XML读入内存时,就会构造一个树状表示。在这种表示法中,所有类型的对象都是节点;元素是节点,属性是节点,文本内容是节点

现在,一个XPath表达式

Ralls, Kim  Adventure   Midnight Rain
Ralls, Kim  Mystery     Some Mystery Book
选择一个元素节点(或者,可能是一组元素节点)。在您的例子中,它是一个元素节点,其子节点是文本节点。将路径表达式扩展到

/catalog/book/author

仅选择
author
元素的子文本节点。理解元素及其文本内容不相同很重要。

不熟悉VBA,但很可能是因为这一行

Title = Author(i).ParentNode.SelectSingleNode("title")
Author
变量(?)设置为字符串值,
text()
表示作为上下文元素直接子元素的所有文本节点的串联。字符串与元素非常不同,它们没有属性或子元素

它们确实有一个父节点,但是

Set Author = XMLFile.SelectNodes("/catalog/book/author/text()")
将尝试检索这样一个文本节点的父节点的
id
属性,它是
author
元素-但是
author
元素没有
id
属性

改变

BookType = Author(i).ParentNode.getAttribute("id")

如果有帮助,请告诉我


编辑:我想我找到了一个可行的解决方案,下面如何。然而,我完全不熟悉VBA-我相信这不是一个非常优雅的解决方案,可以改进很多

Set Author = XMLFile.SelectNodes("/catalog/book/author")
结果

Sub mySub()

Dim XMLFile As MSXML2.DOMDocument
Dim Author As Variant
Dim athr As String, BookType As String, Title As String
Dim AuthorArray() As String, BookTypeArray() As String, TitleArray() As String
Dim i As Long, x As Long, j As Long

Dim mainWorkBook As Workbook
Dim n As IXMLDOMNode
Set mainWorkBook = ActiveWorkbook
Set XMLFile = CreateObject("Microsoft.XMLDOM")
XMLFile.Load ("vba.xml")


x = 1
j = 0

Set Author = XMLFile.SelectNodes("/catalog/book/author")
For i = 0 To (Author.Length - 1)
    ReDim Preserve AuthorArray(0 To i)
    ReDim Preserve BookTypeArray(0 To i)
    ReDim Preserve TitleArray(0 To i)
    athr = Author(i).Text
    BookType = Author(i).ParentNode.getAttribute("id")
    Title = Author(i).ParentNode.getElementsByTagName("title").Item(0).nodeTypedValue

    If athr = "Ralls, Kim" Then

        AuthorArray(j) = athr
        BookTypeArray(j) = BookType
        TitleArray(j) = Title

        j = j + 1
        x = x + 1
    End If
Next



Range("A3:A" & UBound(AuthorArray) + 1) = WorksheetFunction.Transpose(AuthorArray)
Range("B3:B" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(BookTypeArray)
Range("C3:C" & UBound(BookTypeArray) + 1) = WorksheetFunction.Transpose(TitleArray)


End Sub