2009-05-18 5 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> 

내 목표는 versionID 양식의 위치를 ​​추출하는 것입니다. 정규식 충분히 쉬운 :

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는 문서 헤더의 스키마 변경은 ... 예를 들어 솔루션 버전 및 제품 버전 특성이 위치를 바꿀 경우이 작업 솔루션가 가져 오는 유일한 문제는 (마이크로 소프트가하고있는 일을 사랑한다 이렇게, 보인다).

그래서 위의 결과를 얻을 수 있도록 VB.NET의 XML 구문 분석 기능을 사용하려고했습니다. sans-regex.

_doc.ChildNode(1).HasChildNodes = False 

이 사람이 나를 도울 수 :

내가 필요로하는 정보를 포함 _doc 개체에서

ChildNode, 그러나 그것은 어떤 childNodes에이하지 않는 이유는 무엇입니까?

답변

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

하지만 한 가지, infopathProcessingInstruction 변수를 설정하는 행을 설명 할 수 있습니까?내가 XML 조작을 처음 접했을 때의 질문에서 언급했듯이, 그 행이 어떻게 수행 하는지를 정확히 알 수는 없습니다 : P – Anders

+0

"var infopathProcessingInstruction"행의 XPath는 " "mso-infoPathSolution"의 이름입니다.이 URL은 도움이 될 것입니다 : http://aspalliance.com/515 – David

0

문제는 구문 분석하려는 태그가 실제로 XML 문서의 일부가 아니라는 것입니다. XML-Prolog는 처리 지침이 들어 있습니다. 따라서 요소로 XmlDocument에서 사용할 수 없게됩니다.

나의 유일한 생각은 <을 제거한 후 mso-infoPathSolution 요소 만 XmlDocument로 옮기는 것입니다 (설명서를 살펴 보는 것 외에는이 요소들을 어떻게 볼 수 있습니까?). ? >을 멀리두고 < />으로 바꿉니다. 그런 다음 순서에 관계없이 속성에 액세스 할 수 있습니다.

+0

이 새로운 노드를 새 XmlDocument에 삽입하는 방법에 대한 아이디어가 있으십니까? 나는 상대적으로 XML 파싱 및 조작에 익숙하지 않다. 현재 newNode의 OuterXml을 수정하려고하는데 읽기 전용이므로 퀘스트가 계속됩니다! – Anders