2016-07-23 14 views
0

Ich habe seit zu viele Stunden zu kämpfen, um das Element mit einem bestimmten Attribut mit XPath zu bekommen.Access-Element mit einem bestimmten Attribut mit XPath in VB.net

Es folgt die WSDL-Datei aus dem ich das Element erhalten möchten:

<?xml version="1.0" encoding="UTF-8"?> 

<!-- Copyright Zuora, Inc. 2007 - 2010 All Rights Reserved. --> 

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:zns="http://api.zuora.com/" 
    xmlns:ons="http://object.api.zuora.com/" 
    xmlns:fns="http://fault.api.zuora.com/" 
    targetNamespace="http://api.zuora.com/"> 
    <types> 


<schema attributeFormDefault="qualified" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://object.api.zuora.com/"> 
       <import namespace="http://api.zuora.com/" /> 
       <complexType name="zObject"> 
       <sequence> 
        <element minOccurs="0" maxOccurs="unbounded" name="fieldsToNull" nillable="true" type="string" /> 
        <element minOccurs="0" maxOccurs="1" name="Id" nillable="true" type="zns:ID" /> 
       </sequence> 
      </complexType> 


      <complexType name="AccountingCode" > 
       <complexContent> 
        <extension base="ons:zObject"> 
         <sequence> 
          <element minOccurs="0" name="Category" nillable="true" type="string" /> 
          <element minOccurs="0" name="CreatedById" nillable="true" type="zns:ID" /> 
          <element minOccurs="0" name="CreatedDate" nillable="true" type="dateTime" /> 
          <element minOccurs="0" name="GLAccountName" nillable="true" type="string" /> 
          <element minOccurs="0" name="GLAccountNumber" nillable="true" type="string" /> 
          <element minOccurs="0" name="Name" nillable="false" type="string" /> 
          <element minOccurs="0" name="Notes" nillable="true" type="string" /> 
          <element minOccurs="0" name="Status" nillable="true" type="string" /> 
          <element minOccurs="0" name="Type" nillable="false" type="string" /> 
          <element minOccurs="0" name="UpdatedById" nillable="true" type="zns:ID" /> 
          <element minOccurs="0" name="UpdatedDate" nillable="true" type="dateTime" /> 
         </sequence> 
        </extension> 
       </complexContent> 
      </complexType> 

      <complexType name="AccountingPeriod" > 
       <complexContent> 
        <extension base="ons:zObject"> 
         <sequence> 
          <element minOccurs="0" name="CreatedById" nillable="true" type="zns:ID" /> 
          <element minOccurs="0" name="CreatedDate" nillable="true" type="dateTime" /> 
          <element minOccurs="0" name="EndDate" nillable="true" type="date" /> 
          <element minOccurs="0" name="FiscalYear" nillable="true" type="int" /> 
          <element minOccurs="0" name="Name" nillable="true" type="string" /> 
          <element minOccurs="0" name="Notes" nillable="true" type="string" /> 
          <element minOccurs="0" name="StartDate" nillable="true" type="date" /> 
          <element minOccurs="0" name="Status" nillable="true" type="string" /> 
          <element minOccurs="0" name="UpdatedById" nillable="true" type="zns:ID" /> 
          <element minOccurs="0" name="UpdatedDate" nillable="true" type="dateTime" /> 
         </sequence> 
        </extension> 
       </complexContent> 
      </complexType> 
     </schema> 
    </types> 
</definitions> 

Es gibt mehrere Namespace in dieser WSDL-Datei definiert werden:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:zns="http://api.zuora.com/" 
xmlns:ons="http://object.api.zuora.com/" 
xmlns:fns="http://fault.api.zuora.com/" 
targetNamespace="http://api.zuora.com/"> 

hier unter meinem sehr einfaches Stück Code ist. Iam ziemlich sicher, dass mein Problem auf Namespace ist aber trotz eines versuchen zahlreiche Lösung suchen ich es nicht lösen konnte:

Public Sub constituteLocalDictionnary() 

    Dim pathWsdlFile As String 
    pathWsdlFile = My.Settings.ZuoraUrlWSDL 

    Dim doc As New XmlDocument() 
    doc.Load(pathWsdlFile) 



    Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable) 
    nsmgr.AddNamespace("ns", "http://schemas.xmlsoap.org/wsdl/") 
    nsmgr.AddNamespace("ons", "http://object.api.zuora.com/") 

    Dim myXmlPath As String 
    myXmlPath = "//ns:complexType[@name='" & ZuoraWsdlObjectsList(1) & "']" 

    Dim root As XmlElement = doc.DocumentElement 
    Dim node As XmlNode = root.SelectSingleNode(myXmlPath, nsmgr) 

End Sub 
+0

Alle meine höfliche Formel nach dem Kopieren und Einfügen t gegangen o validiere diesen Beitrag. Es gab einige Hallo alle ... Vielen Dank für jede Hilfe ... solche Sachen :) Sorry für den rought Aspekt des ursprünglichen Beitrags. – stef

Antwort

0

Sie verwendet falsche Namespace complexType Element zu verweisen. complexType in der Tat erbt Standardnamen von seinem übergeordneten Elemente schema anstelle des Wurzelelement, da die Mutter näher ist somit Standardnamensraum von äußeren Elementen Kontext überschreibt:

<schema attributeFormDefault="qualified" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://object.api.zuora.com/"> 
    <import namespace="http://api.zuora.com/" /> 
    <complexType name="zObject"> 
     .... 
    </complexType> 
    .... 
</schema>  

diese Weise Versuchen:

.... 

Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable) 
nsmgr.AddNamespace("ns2", "http://www.w3.org/2001/XMLSchema") 

Dim myXmlPath As String 
myXmlPath = "//ns2:complexType[@name='" & ZuoraWsdlObjectsList(1) & "']" 
+0

Vielen Dank! Das hat mein Problem gelöst. Und ich verstehe jetzt besser, wie man Namensräume richtig anspricht. – stef

+0

@stef Sie sind willkommen. Vergessen Sie nicht, die Antwort zu akzeptieren, die Ihnen angemessener erscheint ([mehr] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)) – har07

+0

Fertig! :) Ich habe den Code auf diese Weise implementiert. – stef

0

Code ist sehr einfach mit Xml Linq

Imports System.Xml 
Imports System.Xml.Linq 

Module Module1 
    Const FILENAME As String = "c:\temp\test.xml" 
    Sub Main() 
     Dim doc As XDocument = XDocument.Load(FILENAME) 
     Dim results = doc.Descendants().Where(Function(x) x.Name.LocalName = "complexType").Select(Function(y) New With { _ 
       .name = y.Attribute("name"), 
       .elements = y.Descendants(y.Name.Namespace + "element").Select(Function(z) New With { _ 
        .minOccurs = CType(z.Attribute("minOccurs"), Integer), _ 
        .name = CType(z.Attribute("name"), String), _ 
        .nillable = CType(z.Attribute("nillable"), Boolean), _ 
        .type = CType(z.Attribute("type"), String) _ 
       }).ToList() 
     }).ToList() 
    End Sub 

End Module 
+0

Danke, aber ich ging mit XPath-Lösung auf ce mein Name Raum wurde gelöst. Ich kann dasselbe einfach mit XPAth machen als mit Linq ("// ns: complexType [@ name = '" & ZuoraWsdlObjectsList (1) & "']/ns: complexContent/ns: extension/ns: sequenz/ns: element ") und ein selectNodes anstelle von SelectSingleNode – stef

+0

Meine Lösung ist generisch und funktioniert mit jedem Namespace. Ich extrahiere den Namespace aus den XML-Daten, anstatt den Namespace hart zu codieren. Meine Lösung erhält auch ein Array von complexType, während Ihre Lösung nur einen einzigen complexType erhält. – jdweng

+0

Tatsächlich hast du recht. Ich habe das nicht präzisiert, aber in meiner Lösung muss ich direkt zu einem spezifischen complectType-Element gehen, das einen Namen hat (gespeichert im mehrdimensionalen Array ZuoraWsdlObjectsList) und dann bekomme ich alle Elemente von dort in einem anderen Array, was genau das ist, was ich brauche. Aber sicher werde ich Ihre Lösung sehen und vielleicht werde ich meine Meinung ändern. :) Vielen Dank. – stef