excel - VBA XML : Find root nodes for multiple namespaces

标签 excel xml vba parsing namespaces

我有一个定义了多个命名空间的 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
输出
Spreadsheet output

关于excel - VBA XML : Find root nodes for multiple namespaces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66675363/

相关文章:

vba - 当作为 VBA .xlam 加载时,功能区无效在 Excel 2007 中不起作用

SQL - 空白默认命名空间

vba - 显示单元格的公式,但显示值而不是引用

excel - Sum Column 基于前 12 列的行条目(滚动计数)

时间:2019-05-17 标签:c#openxmlexcelstylesheetbordererror

c# - 在读取 Excel 文件时跳过第一行

excel - 使用 Excel Power Query 将 Parse 类导出到 Excel?

java - 使用 xpath 解析 jaxb 的 xml

xml - 用 xpath 拆分 xml 值并检查字符串位置

vba - 为什么 wbk.wks.Range 不起作用?当我使用工作簿和工作表名称时它可以工作