根据节点属性将XML文件拆分为不同的XML文件

时间:2016-12-29 19:01:47

标签: xml vb.net

我想根据某个节点的不同属性拆分XML文件,创建分离的XML文件,所有文件的顶部都有相同的节点,后跟节点+属性及其底层内容,直到该节点结束。

所有分离的XML文件,不需要以类似的结束节点结束。

示例XML文件:

<?xml version=""1.0"" encoding=""UTF-8""?>
<node1>
  <node2>
    <node3 attribute='1'>item</node3>
    <node3 attribute='2'>item</node3>
    <node3 attribute='3'>item</node3>
  </node2>
<node6 attribute='1'>
    <node7>item = (node3 attribute2)</node7>
    <node8>item = (node3 attribute3)</node8>
</node6>
<node6 attribute='2'>
    <node9>item = (node3 attribute1)</node9>
    <node10>item = (node3 attribute2)</node10>
</node6>
</node1>

从这个例子中我想使用node6的属性作为创建新XML文件的断点。 导致2个XML文件如下所示:

分离的XML 1:

<?xml version=""1.0"" encoding=""UTF-8""?>
<node1>
  <node2>
    <node3 attribute='1'>item</node3>
    <node3 attribute='2'>item</node3>
    <node3 attribute='3'>item</node3>
  </node2>
<node6 attribute='1'>
    <node7>item = (node3 attribute2)</node7>
    <node8>item = (node3 attribute3)</node8>
</node6>

分离的XML 2:

<?xml version=""1.0"" encoding=""UTF-8""?>
<node1>
  <node2>
    <node3 attribute='1'>item</node3>
    <node3 attribute='2'>item</node3>
    <node3 attribute='3'>item</node3>
  </node2>
<node6 attribute='2'>
    <node9>item = (node3 attribute1)</node9>
    <node10>item = (node3 attribute2)</node10>
</node6>
</node1>

我一直在寻找和处理所有这些答案,但它们并没有帮助我找到正确的代码,如上所述。

https://stackoverflow.com/questions/30374533/split-xml-files-newbie

How to split an xml file in vb

Splitting Xml Document according to node

有人可以帮我弄清楚最好的办法是什么?

2 个答案:

答案 0 :(得分:0)

我知道您专门询问了VB解决方案,但是,这里是您可以适应的C#。

<?xml version="1.0"?>
<node1>
  <node2>
    <node3 attribute="1">item</node3>
    <node3 attribute="2">item</node3>
    <node3 attribute="3">item</node3>
  </node2>
<node6 attribute="1">
    <node7>item = (node3 attribute2)</node7>
    <node8>item = (node3 attribute3)</node8>
</node6>
<node6 attribute="2">
    <node9>item = (node3 attribute1)</node9>
    <node10>item = (node3 attribute2)</node10>
</node6>
</node1>

输入文件是这样的:

<?xml version="1.0" encoding="utf-8"?>
<node1>
  <node2>
    <node3 attribute="1">item</node3>
    <node3 attribute="2">item</node3>
    <node3 attribute="3">item</node3>
  </node2>
  <node6 attribute="1">
    <node7>item = (node3 attribute2)</node7>
    <node8>item = (node3 attribute3)</node8>
  </node6>
</node1>

有2个文件,看起来像这样: Data_out1.xml

<?xml version="1.0" encoding="utf-8"?>
<node1>
  <node2>
    <node3 attribute="1">item</node3>
    <node3 attribute="2">item</node3>
    <node3 attribute="3">item</node3>
  </node2>
  <node6 attribute="2">
    <node9>item = (node3 attribute1)</node9>
    <node10>item = (node3 attribute2)</node10>
  </node6>
</node1>

data_out2.xml

{{1}}

答案 1 :(得分:0)

谢谢大家的支持!

使用Bibek Gautam的question and answer作为参考和来自所有人和其他人的反馈我使用以下工作代码(在单独的类中)将所提到的示例XML划分为包含公共字符串和文件的单独XML文件使用节点7,8,9和10作为对哪个节点3属性应该在公共字符串中的引用的特定字符串,从而排除其他节点3的可能性。

代码包含示例XML中未提及的一些额外节点。

我发布了几乎完整的代码,因此具有类似目标的其他人可以将其作为参考。

代码:

Shared Sub CreateXML()

    Dim xOrgXml As New XmlDocument
    Dim pSavelocation As String = "mysavelocation"
    Dim pProgressbar As ProgressBar = Form3.f3.ProgressBar1
    Dim cCommonString As String
    Dim dDocumentRootNodes As XmlNodeList
    'implemented progessbar'
    Dim mProgressBarMaximum As Integer         
    Dim mFoldername As String

    Try
        'Public class containing shared location of source XML'
        xOrgXml.Load(ClsSharedProperties.filePath)
        cCommonString = "<?xml version=""1.0""?>" & "<Node1>"
        dDocumentRootNodes = xOrgXml.GetElementsByTagName("Node1")
        mProgressBarMaximum = xOrgXml.GetElementsByTagName("Node6").Count + xOrgXml.GetElementsByTagName("Node3").Count

        pProgressbar.Minimum = 0
        pProgressbar.Maximum = mProgressBarMaximum
        pProgressbar.Value = 0
        pProgressbar.Visible = True

        '==================================================================================================================='
        'Building Common String'   
        '==================================================================================================================='

        For Each Node1Node As XmlNode In dDocumentRootNodes
            Dim Node1ChildNodes As XmlNodeList = Node1Node.ChildNodes

            For Each Node1Childnode As XmlNode In Node1ChildNodes
                If Node1Childnode.Name = "node4" Then
                    cCommonString = cCommonString & Node1Childnode.OuterXml

                Else
                    If Node1Childnode.Name = "node5" Then
                        cCommonString = cCommonString & Node1Childnode.OuterXml

                    Else
                        If Node1Childnode.Name = "node12" Then
                            cCommonString = cCommonString & Node1Childnode.OuterXml
                        End If
                    End If
                End If
            Next
        Next

        Dim mXMLDocSave As XmlDocument
        Dim mFileName As String
        Dim fFullString As String

        mXMLDocSave = New XmlDocument()

        '=============================================================='
        'Creating Directories and files For xml Getting Name and attribute value from Node6-NODE1node'
        '==============================================================='

        For Each Node1Node As XmlNode In dDocumentRootNodes
            Dim Node1ChildNodes As XmlNodeList = Node1Node.ChildNodes
            For Each NODE1node As XmlNode In Node1ChildNodes

                If NODE1node.Name = "Node6" Then

                    Dim Node6Attribute As XmlAttributeCollection = NODE1node.Attributes
                    If Node6Attribute.GetNamedItem("attribute").Value = "1" Then
                        pProgressbar.Increment(1)
                        Dim cCommonStringNode6_1 As String = cCommonString

                        Dim i As Integer
                        Dim s As String

                        For i = 0 To (Form3.f3.CheckedListBox1.Items.Count - 1)
                            If Form3.f3.CheckedListBox1.GetItemChecked(i) = True Then
                                s = Form3.f3.CheckedListBox1.Items(i).ToString
                                If s = "EXAMPLE A" Then
                                    mFoldername = "EXAMPLE A"
                                    If (Not IO.Directory.Exists(pSavelocation & "\" & mFoldername)) Then
                                        IO.Directory.CreateDirectory(pSavelocation & "\" & mFoldername)
                                    End If
                                ElseIf s = "EXAMPLE B" Then
                                    mFoldername = "EXAMPLE B"
                                    If (Not IO.Directory.Exists(pSavelocation & "\" & mFoldername)) Then
                                        IO.Directory.CreateDirectory(pSavelocation & "\" & mFoldername)
                                    End If
                                End If
                            End If
                        Next
                        For i = 0 To (Form3.f3.CheckedListBox1.Items.Count - 1)
                            If Form3.f3.CheckedListBox1.GetItemChecked(i) = True Then
                                s = Form3.f3.CheckedListBox1.Items(i).ToString
                                If s = "EXAMPLE A" Then
                                    mFileName = Date.Now.ToString("yyyyMMdd-HHmm") + "_" + NODE1node.Name.ToString + "_" + (Node6Attribute.GetNamedItem("attribute").Value).ToString + "_" + "EXAMPLE A"
                                    mFileName = mFileName.Replace(".", "_").Replace(" ", "_").Replace("''", "_").Replace("<", "").Replace(">", "").Replace("d", "D")
                                ElseIf s = "EXAMPLE B" Then
                                    mFileName = Date.Now.ToString("yyyyMMdd-HHmm") + "_" + NODE1node.Name.ToString + "_" + (Node6Attribute.GetNamedItem("attribute").Value).ToString + "_" + "EXAMPLE B"
                                    mFileName = mFileName.Replace(".", "_").Replace(" ", "_").Replace("''", "_").Replace("<", "").Replace(">", "").Replace("d", "D")

                                End If
                            End If
                        Next
                        For Each Node1Node2 As XmlNode In dDocumentRootNodes
                            Dim Node1ChildNodes2 As XmlNodeList = Node1Node2.ChildNodes
                            For Each NODE1node2 As XmlNode In Node1ChildNodes2

                                If NODE1node2.Name = "Node3" Then
                                    pProgressbar.Increment(1)
                                    Dim xNode6Node3List As XmlNodeList = xOrgXml.SelectNodes("/Node1/Node6[@attribute='1']//Node3")

                                    For Each Node6NODE3_Name As XmlNode In xNode6Node3List
                                        pProgressbar.Increment(1)
                                        If (Node6NODE3_Name.InnerText).ToString = (NODE1node2.Attributes("attribute").Value).ToString Then

                                            Dim NODE1_NODE3_Node_String As String = NODE1node2.OuterXml.ToString
                                            'check if node specific string already contains the selected node. If not add it else skip it'
                                            If cCommonStringNode6_1.Contains(NODE1_NODE3_Node_String) = False Then
                                                cCommonStringNode6_1 = cCommonStringNode6_1 & NODE1node2.OuterXml
                                            End If
                                        End If
                                    Next
                                End If
                            Next
                        Next
                        'create the fullstring to be saved as new XML document'
                        fFullString = cCommonStringNode6_1 & NODE1node.OuterXml & "</Node1>"
                        mXMLDocSave.LoadXml(fFullString)
                        'Make all node6 attributes have value "1"'
                        For Each node2 As XmlAttribute In mXMLDocSave.SelectNodes("//Node6/@attribute")
                            node2.Value = "1"
                        Next
                        Dim countervalue As Integer = 0
                        For Each Node1Childnode As XmlNode In mXMLDocSave.SelectNodes("/Node1/Node3")
                            If Node1Childnode.Name = "Node3" Then

                                Dim NODE3_NodeList As XmlNodeList = Node1Childnode.ChildNodes
                                For Each NODE3_Node As XmlNode In NODE3_NodeList

                                    If NODE3_Node.Name = "Node11" Then
                                        countervalue += 1
                                        NODE3_Node.InnerText = countervalue.ToString
                                    End If
                                Next
                            End If
                        Next
                        mXMLDocSave.Save(pSavelocation & "\" & mFoldername & "\" & mFileName & ".xml")
                        mXMLDocSave = New XmlDocument()
                        fFullString = String.Empty
                        mFoldername = String.Empty
                        mFileName = String.Empty
                        End If
                End If
            Next
        Next
    Catch ex As Exception
        MessageBox.Show(ex.Message & vbCrLf & "Stack Trace: " & vbCrLf & ex.StackTrace)
    End Try