2009-05-18 7 views
1

Eine mögliche (in Betrieb) Lösung:

Private Sub ReadXMLAttributes(ByVal oXML As String) 
    ReadXMLAttributes(oXML, "mso-infoPathSolution") 
End Sub 
Private Sub ReadXMLAttributes(ByVal oXML As String, ByVal oTagName As String) 
    Try 
     Dim XmlDoc As New Xml.XmlDocument 
     XmlDoc.LoadXml(oXML) 
     oFileInfo = New InfoPathDocument 
     Dim XmlNodes As Xml.XmlNodeList = XmlDoc.GetElementsByTagName(oTagName) 
     For Each xNode As Xml.XmlNode In XmlNodes 
      With xNode 
       oFileInfo.SolutionVersion = .Attributes(InfoPathSolution.solutionVersion).Value 
       oFileInfo.ProductVersion = .Attributes(InfoPathSolution.productVersion).Value 
       oFileInfo.PIVersion = .Attributes(InfoPathSolution.PIVersion).Value 
       oFileInfo.href = .Attributes(InfoPathSolution.href).Value 
       oFileInfo.name = .Attributes(InfoPathSolution.name).Value 
      End With 
     Next 
    Catch ex As Exception 
     MsgBox(ex.Message, MsgBoxStyle.OkOnly, "ReadXMLAttributes") 
    End Try 
End Sub 

Dies funktioniert, aber es wird immer noch von dem Problem unter leiden, wenn die Attribute werden neu geordnet. Die einzige Möglichkeit, dieses Problem zu vermeiden, besteht darin, die Attributnamen in meinem Programm fest zu codieren und den Eintrag zu verarbeiten, indem es das analysierte Tag durchläuft und nach den angegebenen Tags sucht.Lesen von XML-Tag-Informationen in VB.NET

HINWEIS: InfoPathDocument eine benutzerdefinierte Klasse, die ich gemacht, es ist nichts kompliziert:

Public Class InfoPathDocument 
    Private _sVersion As String 
    Private _pVersion As String 
    Private _piVersion As String 
    Private _href As String 
    Private _name As String 
    Public Property SolutionVersion() As String 
     Get 
      Return _sVersion 
     End Get 
     Set(ByVal value As String) 
      _sVersion = value 
     End Set 
    End Property 
    Public Property ProductVersion() As String 
     Get 
      Return _pVersion 
     End Get 
     Set(ByVal value As String) 
      _pVersion = value 
     End Set 
    End Property 
    Public Property PIVersion() As String 
     Get 
      Return _piVersion 
     End Get 
     Set(ByVal value As String) 
      _piVersion = value 
     End Set 
    End Property 
    Public Property href() As String 
     Get 
      Return _href 
     End Get 
     Set(ByVal value As String) 
      If value.ToLower.StartsWith("file:///") Then 
       value = value.Substring(8) 
      End If 
      _href = Form1.PathToUNC(URLDecode(value)) 
     End Set 
    End Property 
    Public Property name() As String 
     Get 
      Return _name 
     End Get 
     Set(ByVal value As String) 
      _name = value 
     End Set 
    End Property 
    Sub New() 

    End Sub 
    Sub New(ByVal oSolutionVersion As String, ByVal oProductVersion As String, ByVal oPIVersion As String, ByVal oHref As String, ByVal oName As String) 
     SolutionVersion = oSolutionVersion 
     ProductVersion = oProductVersion 
     PIVersion = oPIVersion 
     href = oHref 
     name = oName 
    End Sub 
    Public Function URLDecode(ByVal StringToDecode As String) As String 
     Dim TempAns As String = String.Empty 
     Dim CurChr As Integer = 1 
     Dim oRet As String = String.Empty 
     Try 
      Do Until CurChr - 1 = Len(StringToDecode) 
       Select Case Mid(StringToDecode, CurChr, 1) 
        Case "+" 
         oRet &= " " 
        Case "%" 
         oRet &= Chr(Val("&h" & Mid(StringToDecode, CurChr + 1, 2))) 
         CurChr = CurChr + 2 
        Case Else 
         oRet &= Mid(StringToDecode, CurChr, 1) 
       End Select 
       CurChr += 1 
      Loop 
     Catch ex As Exception 
      MsgBox(ex.Message, MsgBoxStyle.OkOnly, "URLDecode") 
     End Try 
     Return oRet 
    End Function 
End Class 

Original Question

ich an einem Projekt arbeite, die das Lesen eines XML-Dokuments erfordert, insbesondere eine gespeicherte Formular von Microsoft InfoPath.

Hier ist ein einfaches Beispiel dafür, was ich mit einigen Hintergrundinformationen wird die Arbeit mit entlang, die hilfreich sein könnten:

<?xml version="1.0" encoding="UTF-8"?> 
<?mso-infoPathSolution solutionVersion="1.0.0.2" productVersion="12.0.0" PIVersion="1.0.0.0" href="file:///C:\Users\darren\Desktop\simple_form.xsn" name="urn:schemas-microsoft-com:office:infopath:simple-form:-myXSD-2009-05-15T14-16-37" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2009-05-15T14:16:37" xml:lang="en-us"> 
    <my:first_name>John</my:first_name> 
    <my:last_name>Doe</my:last_name> 
</my:myFields> 

Mein Ziel ist jetzt die versionID und die Position der Form zu extrahieren. Leicht genug mit regex:

Dim _doc As New XmlDocument 
_doc.Load(_thefile) 
Dim oRegex As String = "^solutionVersion=""(?<sVersion>[0-9.]*)"" productVersion=""(?<pVersion>[0-9.]*)"" PIVersion=""(?<piVersion>[0-9.]*)"" href=""(?<href>.*)"" name=""(?<name>.*)""$" 
Dim rx As New Regex(oRegex), m As Match = Nothing 
For Each section As XmlNode In _doc.ChildNodes 
    m = rx.Match(section.InnerText.Trim) 
    If m.Success Then 
     Dim temp As String = m.Groups("name").Value.Substring(m.Groups("name").Value.ToLower.IndexOf("infopath") + ("infopath").Length + 1) 
     fileName = temp.Substring(0, temp.LastIndexOf(":")) 
     fileVersion = m.Groups("sVersion").Value 
    End If 
Next 

Das einzige Problem, dass diese Arbeitslösung bringt, wenn die Schemaänderungen in dem InfoPath Belegkopf ... zum Beispiel LIEBT die Lösung Version und Produktversion Eigenschaften Standorte tauschen (microsoft, Dinge zu tun so scheint es).

Also habe ich mich entschieden zu versuchen, die XML-Parsing-Fähigkeit von VB.NET zu verwenden, um mir zu helfen, die oben genannten Ergebnisse, Sans-Regex zu erreichen.

Die ChildNode aus dem _doc Objekt, das die Informationen, die ich enthält benötigen, jedoch hat es keinen Childnodes hat:

_doc.ChildNode(1).HasChildNodes = False 

Kann jemand mir helfen mit dieser aus?

Antwort

1

Die Verarbeitungsanweisungen sind Teil des XML-Dokuments, aber ihre Attribute werden nicht analysiert. Versuchen Sie diesen Code:

// Load the original xml... 
var xml = new XmlDocument(); 
xml.Load(_thefile); 

// Select out the processing instruction... 
var infopathProcessingInstruction = xml.SelectSingleNode("/processing-instruction()[local-name(.) = \"mso-infoPathSolution\"]"); 

// Since the processing instruction does not expose it's attributes, create a new XML document... 
var xmlInfoPath = new XmlDocument(); 
xmlInfoPath.LoadXml("<data " + infopathProcessingInstruction.InnerText + " />"); 

// Get the data... 
var solutionVersion = xmlInfoPath.DocumentElement.GetAttribute("solutionVersion"); 
var productVersion = xmlInfoPath.DocumentElement.GetAttribute("productVersion"); 
+0

Super, danke dafür! – Anders

+0

Eine Sache, konnten Sie die Linie erklären, die die infopathProcessingInstruction Variable setzt?Wie ich in der Frage erwähnt habe, bin ich neu in der XML-Manipulation, also sehe ich nicht genau, wie diese Zeile das ausführt, was sie tut: P – Anders

+0

Der XPath in der Zeile "var infopathProcessingInstruction" sagt "gib mir die erste Verarbeitungsanweisung, die eine hat Name von "mso-infoPathSolution". Diese URL könnte helfen: http://aspalliance.com/515 – David

0

Problem ist, dass die Tags, die Sie analysieren möchten, nicht wirklich Teil des XML-Dokuments sind. Sie sind der XML-Prolog, der die Verarbeitungsanweisungen enthält. Daher werden sie im XmlDocument nicht als Elemente verfügbar sein.

Meine einzige Idee wäre (abgesehen von der Suche durch die Dokumentation, wie man diese Elemente zugreifen konnte) nur die mso-infoPathSolution-Element in ein XmlDocument seiner eigenen zu bewegen, nachdem die < Strippen? ? > weg und ersetzen sie mit < />. Dann können Sie auf die Attribute unabhängig von ihrer Reihenfolge zugreifen.

+0

Haben Sie Ideen, wie Sie diesen bestimmten Knoten in ein neues XmlDocument einfügen? Ich bin relativ neu in Xml Parsing und Manipulation. Momentan versuche ich, die OuterXml von newNode zu modifizieren, aber es ist ReadOnly, also geht die Suche weiter! – Anders