2009-05-18 16 views
1

一つの可能​​(作業)ソリューション:

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 

これは動作しますが、それはまだ問題から属性を並べ替えている場合は、以下苦しむことになります。この問題を避けるために考えられる唯一の方法は、プログラムに属性名をハードコードし、解析されたタグをループして指定されたタグを検索してエントリを処理させることです。読書XMLタグ情報

注:

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 

元の質問、特に保存されたXML文書の読み取りを必要とし、私はプロジェクトに取り組んでいます

:InfoPathDocumentは私が作ったカスタムクラスである、それは複雑なものではありませんフォームをMicrosoft InfoPathから削除します。ここで

は私が役に立つかもしれませんいくつかの背景情報と一緒に働くことになるかの簡単な例です:今

<?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> 

私の目標は、バージョンID、フォームの位置を抽出することです。正規表現で十分簡単:

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 

のInfoPath文書のヘッダー内のスキーマの変更が...インスタンスのソリューション版と製品版の特性が場所を交換する場合は、この作業溶液を立ち上げることを唯一の問題は、(Microsoftが物事を愛していますこのように見える)。

私はVB.NETのXML解析能力を使用して上記の結果を達成するのに役立つことを選択しました、sans-regex。

私は必要な情報が含まれてい_docオブジェクトからChildNodeが、しかしそれはどんなのChildNodesを持っていない:

_doc.ChildNode(1).HasChildNodes = False 

誰もがこれで私を助けることはできますか?

答えて

1

処理命令はXML文書の一部ですが、その属性は解析されません。このコードを試してください:

// 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

素晴らしいです、ありがとうございます! – Anders

+0

しかし、1つのことは、infopathProcessingInstruction変数を設定する行を説明できますか?私が質問したのはXML操作の初心者なので、その行がどのように機能するのか正確には分かりません:P – Anders

+0

"var infopathProcessingInstruction"行のXPathは、 "私に"mso-infoPathSolution"の名前です。このURLは役立ちます:http://aspalliance.com/515 – David

0

問題は、解析したいタグが実際にXML文書の一部ではないということです。それらは処理命令を含むXML-Prologです。そして、それらは要素としてXmlDocumentで利用できません。

<を取り除いた後で、自分自身のXmlDocumentにmso-infoPathSolution要素だけを移動させるという私の唯一のアイデアはありますか? ? >を離れて< />に置き換えてください。次に、順序に関係なく属性にアクセスできます。

+0

この特定のノードを新しいXmlDocumentに挿入する方法はありますか?私はXmlの解析と操作が比較的新しいです。現在、私はnewNodeのOuterXmlを変更しようとしていますが、それはReadOnlyなのでクエストは続行します! – Anders

関連する問題