1

所以我有一个看起来像这样的 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>

我希望每个标有“工作”的父节点都被压缩。因此,第一个 zip 将是“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

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

4

2 回答 2

1

您的 nSource 和 nDestin 变量是文档中所有 Source 和 Destination 标记的列表,而不仅仅是当前 Job。在您的 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 语句,它匹配当前节点的所有后代,即 Source 标记。

于 2012-11-27T20:52:00.300 回答
0

对于任何寻找答案的人,请查看我想出的解决方案。

[代码] 子主()

    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]
于 2012-12-03T15:01:26.003 回答