我有一个定义了多个命名空间的 XML 文件。我想找出一种快速方法来识别每个不同命名空间的根节点。我正在遍历各种不同的文件源,我需要从一个命名空间移动到下一个命名空间。
我已经尝试了以下例程——它被另一个例程调用,该例程加载 XML 并创建和标注所需的各种变量(xDoc、xRoot、xNS 等)。
我似乎无法弄清楚如何在不知道前缀等的情况下轻松解析命名空间。
Sub CheckNameSpace()
If xDoc.namespaces.Length = 0 Then
bNS = False
xOutRng.Offset(x, 0) = "No namespaces present"
x = x + 1
Else
bNS = True
ReDim xNS(0 To xDoc.namespaces.Length - 1)
For i = 0 To xDoc.namespaces.Length - 1
xNS(i) = xDoc.namespaces(i)
xDoc.SetProperty "SelectionNamespaces", "xmlns:nS" & i & "='" & xNS(i) & "'"
xOutRng.Offset(x, 0) = "Namespace nS" & i & " ="
xOutRng.Offset(x, 1) = xNS(i)
x = x + 1
Next i
End If
Set xRoot = xDoc.DocumentElement
Debug.Print xRoot.Prefix
Set xNodeList = xDoc.SelectNodes("//nS0:*")
End Sub
这是我一直在尝试阅读的示例 XML 文件之一:<?xml version="1.0" encoding="UTF-8"?>
<ResponseEnvelope xmlns="http://www.nwabcdfdfd.com/messagin"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ResponseHeader>
<RequestId>directv_99e0857d-abf3-461c-913e-3ab59c6b5ef6</RequestId>
<ResponseId>1162969</ResponseId>
<MessageVersion>1.10</MessageVersion>
<RequestTimestamp>2013-02-12T17:26:28.172Z</RequestTimestamp>
<ResponseTimestamp>2013-02-12T17:26:50.409Z</ResponseTimestamp>
<SenderId>CarePortal2</SenderId>
<ProgramName />
<TestProdFlag>P</TestProdFlag>
<ResultCode>9</ResultCode>
<Locale>en_US</Locale>
<Errors>
<Error>
<ErrorCode>9</ErrorCode>
<ErrorNumber>90001</ErrorNumber>
<ErrorMessage>System error occurred</ErrorMessage>
<ErrorFieldId />
</Error>
</Errors>
</ResponseHeader>
<ResponseBody xsi:type="CPSingleSignOnResponse">
<PortalUserID>45497</PortalUserID>
<PartyID>1858186</PartyID>
<WarrantyItemName>DTV ABC WOLE HE P</WarrantyItemName>
<WarrantyInventoryItemId>138677</WarrantyInventoryItemId>
<ClientWarrantySku>202</ClientWarrantySku>
<ClientWarrantyDescription>DV Plan</ClientWarrantyDescription>
<ContractNumber>4003564</ContractNumber>
<IsPortalUserCreated>N</IsPortalUserCreated>
<IsPartyCreated>N</IsPartyCreated>
<IsContractUpdated>N</IsContractUpdated>
<IsFootPrintUpdated>N</IsFootPrintUpdated>
<Customer>
<PartyId>185812386</PartyId>
<Salutation />
<FirstName>Tejas</FirstName>
<LastName>Tanna</LastName>
<AddressList>
<Address>
<PartySiteId>3617490</PartySiteId>
<Type>BILTO</Type>
<Address1>CASCADES</Address1>
<Address2>202</Address2>
<Address3>RIDGE HEAVEN</Address3>
<Address4 />
<City>STERLING</City>
<State>VA</State>
<PostalCode>20165</PostalCode>
<County>LOUDOUN</County>
<Province />
<Country>US</Country>
<Urbanization />
<AddressStyle>US</AddressStyle>
</Address>
<Address>
<PartySiteId>3613791</PartySiteId>
<Type>SHIP_T</Type>
<Address1>CASADS</Address1>
<Address2>22</Address2>
<Address3>RIE HEEN</Address3>
<Address4 />
<City>STELI</City>
<State>VA</State>
<PostalCode>2065</PostalCode>
<County>LOUUN</County>
<Province />
<Country>US</Country>
<Urbanization />
<AddressStyle>US</AddressStyle>
</Address>
</AddressList>
<PhoneList>
<Phone>
<ContactPointId>2371717</ContactPointId>
<Type>HOME PNE</Type>
<PhoneNumber>51-62-7464</PhoneNumber>
<Country>1</Country>
<PrimaryFlag>Y</PrimaryFlag>
</Phone>
</PhoneList>
<EmailList>
<Email>
<ContactPointId>237516</ContactPointId>
<EmailAddress>a.abc@abc.com</EmailAddress>
<PrimaryFlag>Y</PrimaryFlag>
</Email>
</EmailList>
</Customer>
</ResponseBody>
</ResponseEnvelope>
最佳答案
虽然还有其他带前缀的命名空间,但已发布的 XML 文档中的所有元素都没有带前缀的名称。因此,出于解析的目的,不需要这些命名空间。
但是,由于您在 root 中定义了一个没有以冒号分隔的前缀 ( xmlns="http://www.nwabcdfdfd.com/messagin"
) 的默认命名空间,因此所有底层后代元素都封装在其中。但是,您仍然可以运行 XPath 解析,而无需按名称引用任何元素,例如 //*
.下面将文档中的每个元素解析为电子表格列。
Public Sub ParseXMLElements()
On Error GoTo ErrHandler
Dim xmlDoc As MSXML2.DOMDocument60
Dim xmlNodeList As MSXML2.IXMLDOMNodeList
Dim i As Integer
Dim var As Variant
Dim xml_document_as_string As String
' INITIALIZE AND LOAD XML DOC
Set xmlDoc = New MSXML2.DOMDocument60
xmlDoc.async = False
xmlDoc.Load "C:\Path\To\Document.xml" ' LOAD FROM FILE
' xmlDoc.LoadXML xml_document_as_string ' LOAD FROM STRING
' PARSES ALL ELEMENTS IN DOCUMENT
Set xmlNodeList = xmlDoc.SelectNodes("//*")
' OUTPUT TAG AND TEXT IN WORKSHEET
With Worksheets("MAIN") ' ADJUST SHEET NAME
i = 1
' PARSE ALL NODE NAME AND TEXT TO CELLS
For Each var In xmlNodeList
.Cells(i, 1) = var.nodeName
.Cells(i, 2) = var.Text
i = i + 1
Next var
End With
ExitHandler:
Set xmlDoc = Nothing
Set xmlNodeList = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitHandler
End Sub
输出 关于excel - VBA XML : Find root nodes for multiple namespaces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66675363/