Create XML Nodes based on XPath?

后端 未结 12 608
囚心锁ツ
囚心锁ツ 2020-11-27 15:36

Does anyone know of an existing means of creating an XML hierarchy programatically from an XPath expression?

For example if I have an XML fragment such as:

12条回答
  •  南方客
    南方客 (楼主)
    2020-11-27 15:56

    I liked Chris' version because it handled attributes in xpaths and the other solutions didn't (though it doesn't handle "text()" in the path that well which I fixed). I unfortunately had to use this in a VB app, so here's the conversion for that:

            Private Sub SplitOnce(ByVal value As String, ByVal separator As String, ByRef part1 As String, ByRef part2 As String)
            If (value IsNot Nothing) Then
                Dim idx As Integer = value.IndexOf(separator)
                If (idx >= 0) Then
                    part1 = value.Substring(0, idx)
                    part2 = value.Substring(idx + separator.Length)
                Else
                    part1 = value
                    part2 = Nothing
                End If
            Else
                part1 = ""
                part2 = Nothing
            End If
        End Sub
        Private Function createXPath(ByVal doc As XmlDocument, ByVal xpath As String) As XmlNode
            Dim node As XmlNode = doc
            Dim part As String
            For Each part In xpath.Substring(1).Split("/")
                Dim nodes As XmlNodeList = node.SelectNodes(part)
                If (nodes.Count > 1) Then
                    Throw New Exception("Xpath '" + xpath + "' was not found multiple times!")
                ElseIf (nodes.Count = 1) Then
                    node = nodes(0)
                    Continue For
                End If
    
                If (part.EndsWith("text()")) Then
                    ' treat this the same as previous node since this is really innertext
                    Exit For
                ElseIf (part.StartsWith("@")) Then
                    Dim anode As XmlAttribute = doc.CreateAttribute(part.Substring(1))
                    node.Attributes.Append(anode)
                    node = anode
                Else
                    Dim elName As String = Nothing
                    Dim attrib As String = Nothing
                    If (part.Contains("[")) Then
                        SplitOnce(part, "[", elName, attrib)
                        If (Not attrib.EndsWith("]")) Then
                            Throw New Exception("Unsupported XPath (missing ]): " + part)
                        End If
                        attrib = attrib.Substring(0, attrib.Length - 1)
                    Else
                        elName = part
                    End If
                    Dim nextnode As XmlNode = doc.CreateElement(elName)
                    node.AppendChild(nextnode)
                    node = nextnode
                    If (attrib IsNot Nothing) Then
                        If (Not attrib.StartsWith("@")) Then
                            Throw New Exception("Unsupported XPath attrib (missing @): " + part)
                        End If
                        Dim name As String = ""
                        Dim value As String = ""
                        SplitOnce(attrib.Substring(1), "='", name, value)
                        If (String.IsNullOrEmpty(value) Or Not value.EndsWith("'")) Then
                            Throw New Exception("Unsupported XPath attrib: " + part)
                        End If
                        value = value.Substring(0, value.Length - 1)
                        Dim anode As XmlAttribute = doc.CreateAttribute(name)
                        anode.Value = value
                        node.Attributes.Append(anode)
                    End If
                End If
            Next
            Return node
        End Function
    

提交回复
热议问题