2016-08-11 11 views
1

Bitte glauben Sie mir, ich wirklich haben googelt und gesucht, aber ich bin ein Neuling zu XML mit VBA. Alle Beispiele, die ich gesehen habe, verwenden etwas, was ich "einfaches" XML nennen würde, und mein Beispiel (für mich) scheint komplizierter. Vor allem hier ist ein einfacher Auszug meiner XML (wenn ich es mit Block Anführungszeichen anfügen verwalten kann)Extrahieren XML-Wert aus Datei mit VBA

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:ec.europa.eu:taxud:tin:services:checkTin" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="urn:ec.europa.eu:taxud:tin:services:checkTin:types" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ec.europa.eu:taxud:tin:services:checkTin"> 
    <wsdl:types> 
     <xsd:schema xmlns="urn:ec.europa.eu:taxud:tin:services:checkTin:types" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="urn:ec.europa.eu:taxud:tin:services:checkTin:types"> 
     <xsd:element name="checkTin"> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element name="FR" type="xsd:string" /> 
        <xsd:element name="98-0242041" type="xsd:string" /> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="checkTinResponse"> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element name="countryCode" type="xsd:string" /> 
        <xsd:element name="tinNumber" type="xsd:string" /> 
        " 
        <xsd:element name="requestDate" type="xsd:date" /> 
        <xsd:element name="validStructure" type="xsd:boolean" /> 
        <xsd:element name="validSyntax" type="xsd:boolean" minOccurs="0" /> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
     .... multiple elements of <xsd:element name="checkTin"> and <xsd:element > name="checkTinResponse"> then follow 
     ..... 
     </xsd:schema> 
    </wsdl:types> 
    <wsdl:message name="checkTinRequest"> 
     <wsdl:part name="parameters" element="tns1:checkTin" /> 
    </wsdl:message> 
    <wsdl:message name="checkTinResponse"> 
     <wsdl:part name="parameters" element="tns1:checkTinResponse" /> 
    </wsdl:message> 
    <wsdl:portType name="checkTinPortType"> 
     <wsdl:operation name="checkTin"> 
     <wsdl:input name="checkTinRequest" message="impl:checkTinRequest" /> 
     <wsdl:output name="checkTinResponse" message="impl:checkTinResponse" /> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="checkTinBinding" type="impl:checkTinPortType"> 
     <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
     <wsdl:operation name="checkTin"> 
     <wsdlsoap:operation soapAction="" /> 
     <wsdl:input name="checkTinRequest"> 
      <wsdlsoap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output name="checkTinResponse"> 
      <wsdlsoap:body use="literal" /> 
     </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="checkTinService"> 
     <wsdl:port name="checkTinPort" binding="impl:checkTinBinding"> 
     <wsdlsoap:address location="https://ec.europa.eu/taxation_customs/tin/services/checkTinService" /> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

habe ich gefunden und getestet, um den folgenden Code

Public Sub LoadDocument() 
Dim XDoc As MSXML2.DOMDocument 
Set XDoc = New MSXML2.DOMDocument 
XDoc.validateOnParse = False 
' The file here is basically the same as the XML code above 
If XDoc.Load("E:\Excel\TIN\KVKF440I.txt") Then 
    ' The document loaded successfully. 
    ' Now do something intersting. 
    DisplayNode XDoc.ChildNodes, 0 
Else 
    ' The document failed to load. 
    ' See the previous listing for error information. 
    ' The document failed to load. 
    Dim strErrText As String 
    Dim xPE As MSXML2.IXMLDOMParseError 
    ' Obtain the ParseError object 
    Set xPE = XDoc.parseError 
    With xPE 
     strErrText = "Your XML Document failed to load" & _ 
      "due the following error." & vbCrLf & _ 
     "Error #: " & .ErrorCode & ": " & xPE.reason & _ 
     "Line #: " & .Line & vbCrLf & _ 
     "Line Position: " & .linepos & vbCrLf & _ 
     "Position In File: " & .filepos & vbCrLf & _ 
     "Source Text: " & .srcText & vbCrLf & _ 
     "Document URL: " & .URL 
    End With 

    MsgBox strErrText, vbExclamation 
End If 

Set XDoc = Nothing 

End Sub 

Public Sub DisplayNode(ByRef Nodes As MSXML2.IXMLDOMNodeList, ByVal Indent As Integer) 

    Dim xNode As MSXML2.IXMLDOMNode 
    Indent = Indent + 2 

    For Each xNode In Nodes 
    ' If xNode.NodeType = NODE_TEXT Then 
     If xNode.ParentNode.nodeName = "xsd:element" Then 
     Debug.Print Space$(Indent) & xNode.ParentNode.nodeName & _ 
      ":" & xNode.NodeValue 
     End If 

     If xNode.HasChildNodes Then 
     DisplayNode xNode.ChildNodes, Indent 
     End If 
    Next xNode 
End Sub 

Grundsätzlich möchte ich Schleife (?) für jedes 'Element name = "checkTin"' und extrahiere die Werte für das Kind 'element name =' (dh, im obigen Beispiel möchte ich FR und 98-0242021 extrahieren). Dann möchte ich das gleiche tun für die entsprechende 'element name = "checkTinResponse"' und extrahiere die 5 Elemente von 'xsd: element name =', die dazu gehören.

Wie gesagt, ich habe viele Beispiele ausprobiert, die ich gefunden habe, aber offensichtlich weiß ich nicht, was ich tue, noch verstehe ich die Ergebnisse, die ich bekomme. Zum Beispiel, ich vermute, dass der kopierte Code über das für xNode.ParentNode.nodeName = "xsd: element" testet, ist nicht wirklich der beste Weg zu gehen.

Alle Vorschläge sehr geschätzt.

Antwort

2

Sie können XPath Ausdrücke verwenden, um die Elemente zu erhalten, die Sie suchen.

Ich habe unter 2 XPath Ausdrücke im Code verwendet:

  • //*[local-name()='schema']/*[local-name()='element']

  • ././/*[local-name()='element']

//*[local-name()='schema']/*[local-name()='element'] verwendet wird, die alle elements unter dem schema Knoten erhalten. Dann schleifen wir jedes Element und verwenden den XPath Ausdruck ././/*[local-name()='element'], um das Kind elements zu erhalten.

Anm .: Bevor Sie das Verfahren ausführen, fügen Sie einen Verweis auf Microsoft Xml, v6.0 hinzu.

Sub GetElements() 
    Dim xmlFileName As String 
    Dim XDoc As DOMDocument60 
    Dim pElements As IXMLDOMNodeList, pElement As IXMLDOMNode 
    Dim chElements As IXMLDOMNodeList, chElement As IXMLDOMNode 

    xmlFileName = "C:\Temp\test.xml"  ''-- set filename appropriately 
    Set XDoc = New DOMDocument60 
    XDoc.validateOnParse = False 
    If XDoc.Load(xmlFileName) Then 
     ''-- The document loaded successfully. 
     Set pElements = XDoc.SelectNodes("//*[local-name()='schema']/*[local-name()='element']") 
     For Each pElement In pElements 
      ''-- print the parent node 
      Debug.Print pElement.Attributes.getNamedItem("name").NodeValue 
      Set chElements = pElement.SelectNodes("././/*[local-name()='element']") 
      For Each chElement In chElements 
       ''-- print the child nodes 
       Debug.Print vbTab & chElement.Attributes.getNamedItem("name").NodeValue 
      Next 
     Next 
    Else 
     ''-- The document failed to load. 
     MsgBox Err.Number & ":" & Err.Description, vbExclamation, "Error" 
    End If 

    Set XDoc = Nothing 

End Sub 

ERGEBNIS:

checkTin 
    FR 
    98-0242041 
checkTinResponse 
    countryCode 
    tinNumber 
    requestDate 
    validStructure 
    validSyntax 
+1

Vielen Dank. Es gibt keinen Weg, wie ich es zu dieser Lösung geschafft hätte. Ich werde später heute Abend zu Hause testen. –

+0

Ich musste den Code in 'Dim XDoc As MSXML2.DOMDocument' und' Set XDoc = New MSXML2.DOMDocument' ändern, aber in der Zeile mit 'Set pElements = XDoc.SelectNodes (" // * [local-name() = 'schema']/* [local-name() = 'element'] ")' Ich habe die Fehlermeldung "Unknown method" –

+0

Die Lösung hier gefunden [link] http://stackoverflow.com/questions/20617236/unknown-method-in-xpath-run-by-vbscript Ich habe die Zeile über SetProperty hinzugefügt und dann funktioniert es gut. Vielen Dank für Ihre ursprüngliche Antwort –