如何在 Outlook VBA 中加载带有 XML 声明的 XML 文件?
How to load an XML file with an XML declaration in Outlook VBA?
我在 Outlook 2017 的集成开发环境中有一个 Outlook 宏。
宏在 xml 文件中搜索包含发件人邮件地址的条目,以找到相应的 "No."。
如果 xml 文件在文件开头不包含 xml 声明,则此方法有效。
我得到的文件都是以这个xml标签开头的,我的应用程序无法处理这个文件。
我用来解析文件的代码如下所示:
Private Function GetVendorNoFromFile(filepath As String, oMail As Outlook.MailItem) As String
Set oXMLFile = CreateObject("Microsoft.XMLDOM")
oXMLFile.Load (filepath)
Set Vendors = oXMLFile.GetElementsByTagName("Vendor")
For Each vendor In Vendors
If LCase(vendor.SelectSingleNode("E-Mail").Text) = LCase(GetSMTPMailAdress(oMail)) Then
GetVendorNoFromFile = vendor.SelectSingleNode("No.").Text
Exit For
End If
Next
End Function
如果文件看起来像这样就可以工作:
<Vendors>
<Vendor>
<No.>No1</No.>
<E-Mail>Mail1</E-Mail>
</Vendor>
<Vendor>
<No.>No2</No.>
<E-Mail>Mail2</E-Mail>
</Vendor>
</Vendors>
但如果文件看起来像这样则不会:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Vendors>
<Vendor>
<No.>No1</No.>
<E-Mail>Mail1</E-Mail>
</Vendor>
<Vendor>
<No.>No2</No.>
<E-Mail>Mail2</E-Mail>
</Vendor>
</Vendors>
更准确地说:变量 "oXMLFile" 有一个属性 "childNodes",它的计数为 1,包含第一个 xml 文件的标签 "Vendors" ,但如果我使用带有 xml 声明的第二个 xml 文件,它的计数为零。
我尝试在加载文件之前添加这些行中的任何一行
oXMLFile.async = False
oXMLFile.validateOnParse = False
但它并没有改变任何东西。
我可以在网上找到的所有示例都以与我相同的方式执行,但它们似乎使用包含 xml 声明的文件。
我找到了问题的原因:
我创建了一个示例 xml 文件,并将我将要使用的 xml 文件的内容复制到新创建的示例文件中。然而,原始文件的格式为 "UCS-2 LE-BOM"(根据 Notepad++),但我从头开始创建的文件格式为 UTF-8。我不假思索地复制了 xml 声明说 "encoding="UTF-16"。
如果我在示例文件中将 xml 声明更改为 "UTF-8",它就可以工作。如果我使用声明为 "UTF-16" 和上述格式的原始文件之一,情况也是如此。我的变量 "oXMLFile" 现在有 2 个 "ChildNodes",一个是 xml 声明标签,另一个是 "Vendors".
我在 Outlook 2017 的集成开发环境中有一个 Outlook 宏。
宏在 xml 文件中搜索包含发件人邮件地址的条目,以找到相应的 "No."。
如果 xml 文件在文件开头不包含 xml 声明,则此方法有效。
我得到的文件都是以这个xml标签开头的,我的应用程序无法处理这个文件。
我用来解析文件的代码如下所示:
Private Function GetVendorNoFromFile(filepath As String, oMail As Outlook.MailItem) As String
Set oXMLFile = CreateObject("Microsoft.XMLDOM")
oXMLFile.Load (filepath)
Set Vendors = oXMLFile.GetElementsByTagName("Vendor")
For Each vendor In Vendors
If LCase(vendor.SelectSingleNode("E-Mail").Text) = LCase(GetSMTPMailAdress(oMail)) Then
GetVendorNoFromFile = vendor.SelectSingleNode("No.").Text
Exit For
End If
Next
End Function
如果文件看起来像这样就可以工作:
<Vendors>
<Vendor>
<No.>No1</No.>
<E-Mail>Mail1</E-Mail>
</Vendor>
<Vendor>
<No.>No2</No.>
<E-Mail>Mail2</E-Mail>
</Vendor>
</Vendors>
但如果文件看起来像这样则不会:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Vendors>
<Vendor>
<No.>No1</No.>
<E-Mail>Mail1</E-Mail>
</Vendor>
<Vendor>
<No.>No2</No.>
<E-Mail>Mail2</E-Mail>
</Vendor>
</Vendors>
更准确地说:变量 "oXMLFile" 有一个属性 "childNodes",它的计数为 1,包含第一个 xml 文件的标签 "Vendors" ,但如果我使用带有 xml 声明的第二个 xml 文件,它的计数为零。
我尝试在加载文件之前添加这些行中的任何一行
oXMLFile.async = False
oXMLFile.validateOnParse = False
但它并没有改变任何东西。
我可以在网上找到的所有示例都以与我相同的方式执行,但它们似乎使用包含 xml 声明的文件。
我找到了问题的原因:
我创建了一个示例 xml 文件,并将我将要使用的 xml 文件的内容复制到新创建的示例文件中。然而,原始文件的格式为 "UCS-2 LE-BOM"(根据 Notepad++),但我从头开始创建的文件格式为 UTF-8。我不假思索地复制了 xml 声明说 "encoding="UTF-16"。
如果我在示例文件中将 xml 声明更改为 "UTF-8",它就可以工作。如果我使用声明为 "UTF-16" 和上述格式的原始文件之一,情况也是如此。我的变量 "oXMLFile" 现在有 2 个 "ChildNodes",一个是 xml 声明标签,另一个是 "Vendors".