1

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

これは機能しますが、属性を並べ替えると、以下の問題が発生します。この問題を回避するために考えられる唯一の方法は、属性名をプログラムにハードコーディングし、解析されたタグをループして指定されたタグを検索することにより、エントリを処理させることです。

注:InfoPathDocumentは私が作成したカスタムクラスであり、複雑なものではありません。

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ドキュメント、特にMicrosoftInfoPathから保存されたフォームを読み取る必要があるプロジェクトに取り組んでいます。

これは、私が作業する内容の簡単な例と、役立つ可能性のあるいくつかの背景情報です。

<?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 LOVESはこのようなことをしているようです)。

そこで、VB.NETのXML解析機能を使用して、上記の結果(sans-regex)を実現できるようにすることにしました。

ChildNode必要な情報を含むオブジェクトからですが、 ChildNode_docはありません。

_doc.ChildNode(1).HasChildNodes = False

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

4

2 に答える 2

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");
于 2009-05-18T19:25:54.887 に答える
0

問題は、解析したいタグが実際には XML ドキュメントの一部ではないことです。これらは、処理命令を含む XML-Prolog です。そのため、XmlDocument で要素として使用することはできません。

私の唯一のアイデアは、<? ?> を削除して < /> に置き換えます。その後、順序に関係なく属性にアクセスできます。

于 2009-05-18T16:51:08.007 に答える