Access VBA ImportXML方法仅从XML文件导入最后一条记录

Access VBA ImportXML方法仅从XML文件导入最后一条记录,xml,ms-access,asp.net-web-api,vba,Xml,Ms Access,Asp.net Web Api,Vba,我正在尝试使用Application.ImportXML方法将一个非常基本的XML文件导入MS Access(2010)。当我查看导入结果时,该表只包含XML文件中的最后一条记录 首先,我在Visual Studio 2017中创建了一个小型ASP.NET Web应用程序(VB.NET),它有一个控制器PersonController.VB。我没有使用默认方法&我已经设置了当前值- 作为IEnumerable(字符串的)的公共函数GetValues() 返回新字符串(){“Person1”,“P

我正在尝试使用Application.ImportXML方法将一个非常基本的XML文件导入MS Access(2010)。当我查看导入结果时,该表只包含XML文件中的最后一条记录

首先,我在Visual Studio 2017中创建了一个小型ASP.NET Web应用程序(VB.NET),它有一个控制器
PersonController.VB
。我没有使用默认方法&我已经设置了当前值-

作为IEnumerable(字符串的)的公共函数GetValues()
返回新字符串(){“Person1”,“Person2”}
端函数
当我通过
iisexpress(googlechrome)
运行它时,我可以通过Postmaster查看XML结果,如下所示-

[“Person1”、“Person2”]
或者如果我选择json-

[
“人1”,
“人2”
]
我选择XML

现在进入我的VBA。我创建了一个新模块来测试将XML导入本地访问表的过程-

选项比较数据库
选项显式
私有常量URL作为字符串=”http://localhost:58372/api/Person"
私有常量路径为String=“C:/Users/my.name/Desktop/”
公共枚举请求ReadyState
未初始化=0
加载
加载
互动的
完整的
结束枚举
当我手动转到
http://localhost:58372/api/Person/
我得到了所需的输出。我在VBA方面有点问题

注意-我为此添加了对
MicrosoftXML,v6.0
库的引用

Public-Sub-Readxml()
Dim读卡器为新XMLHTTP60,文档为MSXML2.DOMDocument60
与读者
'打开对象
.打开“获取”,URL,False
.setRequestHeader“接受”、“应用程序/xml”
'发送在打开中指定的命令
.发送
'等待请求完成,4是已完成状态
”“看到了吗(https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms753800(v=vs.85)
直到.ReadyState=RequestReadyState.COMPLETED完成为止
多芬特
环
'检查是否遇到错误
'状态代码(https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
如果.Status=200,则
“成功了
Set doc=.responseXML
doc.Save路径&“Person.xml”
Application.ImportXML路径和“Person.xml”,acStructureAndData
其他的
”“没有
MsgBox“它已损坏:&.Status&:”&.statusText
出口接头
如果结束
以
“清理
设置读取器=无
如果不是doc,则设置doc=Nothing
终止路径&“Person.xml”
端接头
子进程运行到完成时没有任何错误,但是当我打开新创建的表
ArrayOfstring
时,它只包含1条记录,即“Person2”

我试过解决这个问题,但我迷路了
doc.childNodes.length
返回1(应该是2条记录?),但我不明白为什么

我曾经尝试&帮助我理解生成的XML是否有问题,当我勾选根据外部XML模式进行验证的选项时,会出现以下错误-

cvc elt.1:找不到元素'ArrayOfstring'的声明。

XML文件内容-


人1
人2
`
有人能给我指出正确的方向/发现我在这里错过的东西吗?对不起,如果我对整件事有点漫无边际,只是有点困惑

编辑:我已经更新了引用以使用Microsoft XML v3.0&更新了对象类型以反映新引用,但我仍然遇到同样的问题


Edit2:Update:下面的答案说明转换为不同类型的XML确实有效,但我选择使用不同的解决方案。为了避免使用本地表,我将header请求设置为使用JSON&然后将其解析为一个集合,以便在应用程序中使用。我发现这种方法对我的设置更为顺畅。

问题

当前的结果是有意义的,因为Access的XML迁移将节点名称呈现为列,将文本值呈现为行值,而忽略任何属性。具体如下:

<table_name>
  <col1>value1</col1>
  <col2>value2</col2>
</table_name>
但是,由于XML响应包含两个相同的命名节点(XML中允许),并且数据库表不能具有相同的命名列,因此只有字符串的最后一个实例保留为列

解决方案

要解决的问题是,在通过代码> >获取< /代码>请求下载XML之后,考虑运行XSLT,专用语言来转换XML文件,将节点转换为Strug1和StRIG2:

XSLT(另存为.xsl文件,一个特殊的.xml文件)

XML输出

<?xml version="1.0" encoding="UTF-16"?>
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <string1>Person1</string1>
    <string2>Person2</string2>
</ArrayOfstring>

如果XML文件有多个重复子元素,则多行将传播:

假设的XML

<?xml version="1.0" encoding="UTF-16"?>
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
</ArrayOfstring>

FWIW我试着看到了同样的事情。还尝试了先创建表,然后附加数据的方法-相同的行为。在谷歌搜索中找不到任何其他提及此事的地方。。。Access 2010。谢谢@Cindymister,我自己也一直在努力在网上找到类似的行为。你是说不可能为给定列导入多行吗?不。只是你不能创建包含两个同名列的表。如果在重复的字符串上方有一个父级,则该父级将成为表的名称,重复的字符串将成为行。请参见编辑以显示。再一次,子节点不能重复。@Parfait我不确定是否能够根据我的场景使用它,如果可以的话,我很抱歉,但您能进一步澄清一下吗?正在根据GET请求创建原始XML。我使用application/xml头值来获取信息。当我尝试使用xsl/xslt时,我没有收到有效的文件来处理。继续使用您的
GET
请求。但作为补充
<?xml version="1.0" encoding="UTF-16"?>
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <string1>Person1</string1>
    <string2>Person2</string2>
</ArrayOfstring>
ArrayOfstring

string1    string2
Person1    Person2
<?xml version="1.0" encoding="UTF-16"?>
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
  <newtable>
    <string1>Person1</string1>
    <string2>Person2</string2>
  </newtable>
</ArrayOfstring>
newtable

string1    string2
Person1    Person2
Person1    Person2
Person1    Person2