用XML分隔zip任务

时间:2012-11-27 20:43:59

标签: xml vb.net zip

所以我有一个看起来像这样的XML ......

<?xml version="1.0" encoding="UTF-8"?>

<!--XML Backup.-->
-<Jobs> 
-<Job> 
 <JobName>a</JobName>
   <Source>C:\Users\Public\Pictures\Samplepictures\Lighthouse.jpg</Source> 
    <Source>C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg</Source>  
    <Source>C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg</Source>  
    <Destination>C:\Users\Public\Pictures\Sample Pictures\a.zip</Destination>
   <Timestamp>11/26/2012 6:18:00 PM</Timestamp> 
 </Job> 
-<Job> 
<JobName>b</JobName> 
  <Source>C:\Users\Public\Pictures\demo photo\1 - Copy.JPG</Source>    
  <Source>C:\Users\Public\Pictures\demo photo\1.JPG</Source> 
  <Source>C:\Users\Public\Pictures\demo photo\2 - Copy.JPG</Source> 
  <Destination>C:\Users\Public\Pictures\demo photo\b.zip</Destination> 
  <Timestamp>11/26/2012 6:18:19 PM</Timestamp> 
 </Job> 
</Jobs>

我希望每个标有“作业”的父节点都被压缩。所以第一个拉链是“a.zip”,里面有“tulips.jpg”,“lighthouse.jpg”和“penguins.jpg” - 位于目的地。

第二个zip将是“b.zip”和相应的文件。

现在,我在正确的目的地获得“a.zip”和“b.zip” - 但每个zip包含所有文件。

我现在的代码如下。

   Dim JobNodes As XmlNodeList
    Dim JobNode As XmlNode
    Dim baseDataNodes As XmlNodeList
    Dim bFirstInRow As Boolean

    JobNodes = doc.GetElementsByTagName("Job")
    For Each jobNode In JobNodes
        baseDataNodes = JobNode.ChildNodes
        bFirstInRow = True

        For Each baseDataNode As XmlNode In baseDataNodes

            Dim Source = baseDataNode.SelectNodes("descendant::Source")
            Dim Destin = baseDataNode.SelectNodes("descendant::Destination")
            Using zip As New ZipFile()

                For Each item As System.Xml.XmlElement In Source
                    zip.AddFile(item.InnerText, "Archive_" & DateString)
                Next

                For Each item As System.Xml.XmlElement In Destin
                    zip.Save(item.InnerText)
                Next
            End Using


            Console.Write(vbCrLf)


            Console.Write(baseDataNode.Name & ": " & baseDataNode.InnerText)
        Next

        Console.Write(vbCrLf)
        Console.Write(vbCrLf)
    Next

另外,我很好奇是否有必要使用“后代::”如果是这样,它会做什么?

2 个答案:

答案 0 :(得分:1)

您的nSource和nDestin变量是文档中所有Source和Destination标记的列表,而不仅仅是当前作业。在baseDataNode循环中,您需要为这些变量分配新值。我不知道你工作的Api,但我会尝试类似的东西:

For Each baseDataNode As XmlNode In baseDataNodes
  Dim nSource = baseDataNode.SelectNodes("descendant::Source")
  Dim nDestin = baseDataNode.SelectNodes("descendant::Destination")
  ...

编辑: XmlNode.SelectNodes采用xpath字符串,“descendant::Source”是一个xpath语句,它匹配当前节点的所有后代,这些后代是源标记。

答案 1 :(得分:0)

对于寻找答案的人,请查看我发现的解决方案。

[CODE] Sub main()

    Dim doc As New System.Xml.XmlDocument
    Dim myJob As New Atr.backup.Job

    doc.Load("C:\users\matt taylor\desktop\backup\backup.xml")
    myLogger = New Logger("C:\users\matt taylor\desktop\backup\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log")

    Console.SetWindowSize(100, 25)

    Dim JobNodes As XmlNodeList = doc.GetElementsByTagName("Job")
    Dim JobNode As XmlNode
    Dim baseDataNodes As XmlNodeList


    For Each JobNode In JobNodes
        baseDataNodes = JobNode.ChildNodes()


        For Each baseDataNode As XmlNode In baseDataNodes



            myJob.jobName = JobNode.SelectSingleNode("JobName").Name
            myJob.jobSource = JobNode.SelectSingleNode("Source").Name
            myJob.jobDestination = JobNode.SelectSingleNode("Destination").Name
            myJob.jobTimeStamp = JobNode.SelectSingleNode("Timestamp").Name


            Dim Source = JobNode.SelectNodes("Source")
            Dim Destin = JobNode.SelectNodes("Destination")

            Using zip As New ZipFile()
                For Each item As System.Xml.XmlNode In Source
                    zip.AddFile(item.InnerText, JobNode.SelectSingleNode("JobName").InnerText & "_Archive_" & DateString)
                Next

                For Each item As System.Xml.XmlNode In Destin
                    zip.Save(item.InnerText)
                Next
            End Using


            Console.Write(vbCrLf)

            Console.Write(baseDataNode.Name & ": " & baseDataNode.InnerText)
            myLogger.Log(baseDataNode.Name & ": " & baseDataNode.InnerText)
        Next

        Console.Write(vbCrLf)
        Console.Write(vbCrLf)
    Next

    Console.Read()
End Sub[/CODE]

然后有一个名为JOB的公共类,用于某些例程。

[CODE]公共课程工作

    Private name As String
    Private source As String
    Private destination As String
    Private timeStamp As String


    Public Property jobName() As String
        Get
            Return name
        End Get
        Set(value As String)
            name = value
        End Set
    End Property
    Public Property jobSource() As String
        Get
            Return source

        End Get
        Set(value As String)
            source = value
        End Set
    End Property
    Public Property jobDestination() As String
        Get
            Return destination
        End Get
        Set(value As String)
            destination = value
        End Set
    End Property
    Public Property jobTimeStamp() As String
        Get
            Return timeStamp
        End Get
        Set(value As String)
            timeStamp = value
        End Set
    End Property[/CODE]