简体   繁体   中英

XML Parsing in Powershell

I've tried a few things, but I'm new to parsing XML files and can't seem to get anything to work. Below is an example XML file I need to parse through, but the section shown is repeated 1000s of times over. I need to read the script and identity each Name="TaskName" for every task that contains NewFilesOnly="1" in the Source.

<Task ID="1234" Name="TaskName" Active="1">     
    <Source HostID="servername1" Type="Share" Path="" FileMask="Filename.csv" DeleteOrig="1" NewFilesOnly="1" SearchSubdirs="0" Unzip="0" RetryIfNoFiles="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefDelOldStateDays="1" UseDefStateCaching="1" UseDefRescanSecs="1" UDMxFi="1" UDMxBy="1" UseDefWinCopyFileAPI="1" ID="11"/>
    <Destination HostID="servername2" Type="Share" Path="Incoming" FileName="[OrigName]" UseOrigName="1" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefWinCopyFileAPI="1" ID="12"/>
    <NextActions>
        <NextAction DoIfSuccess="0" DoIfFailure="1" DoIfNoAction="0" DoAfter="Task" Type="Email" HostID="12345" AddressTo="somebody@west.com" Subject="Subject" Message="Message"/>
    </NextActions>
</Task>

I understand the code below isn't valid, but it helps demonstrate the logic that I'm trying to accomplish.

$XML = [xml] (Get-Content C:\files\export.xml)
$SearchString = "*NewFilesOnly=*"

foreach ($Task in <TASK>){
Select-String $SearchString
Write-Host $Task
}

For an XML file (say, test.xml ) like this:

<Tasks>
    <Task ID="1234" Name="TaskName1" Active="1">     
        <Source HostID="servername1" Type="Share" Path="" FileMask="Filename.csv" DeleteOrig="1" NewFilesOnly="1" SearchSubdirs="0" Unzip="0" RetryIfNoFiles="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefDelOldStateDays="1" UseDefStateCaching="1" UseDefRescanSecs="1" UDMxFi="1" UDMxBy="1" UseDefWinCopyFileAPI="1" ID="11"/>
        <Destination HostID="servername2" Type="Share" Path="Incoming" FileName="[OrigName]" UseOrigName="1" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefWinCopyFileAPI="1" ID="12"/>
        <NextActions>
            <NextAction DoIfSuccess="0" DoIfFailure="1" DoIfNoAction="0" DoAfter="Task" Type="Email" HostID="12345" AddressTo="somebody@west.com" Subject="Subject" Message="Message"/>
        </NextActions>
    </Task>
    <Task ID="1235" Name="TaskName2" Active="1">     
        <Source HostID="servername1" Type="Share" Path="" FileMask="Filename.csv" DeleteOrig="1" NewFilesOnly="0" SearchSubdirs="0" Unzip="0" RetryIfNoFiles="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefDelOldStateDays="1" UseDefStateCaching="1" UseDefRescanSecs="1" UDMxFi="1" UDMxBy="1" UseDefWinCopyFileAPI="1" ID="11"/>
        <Destination HostID="servername2" Type="Share" Path="Incoming" FileName="[OrigName]" UseOrigName="1" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefWinCopyFileAPI="1" ID="12"/>
        <NextActions>
            <NextAction DoIfSuccess="0" DoIfFailure="1" DoIfNoAction="0" DoAfter="Task" Type="Email" HostID="12345" AddressTo="somebody@west.com" Subject="Subject" Message="Message"/>
        </NextActions>
    </Task>
    <Task ID="1236" Name="TaskName3" Active="1">     
        <Source HostID="servername1" Type="Share" Path="" FileMask="Filename.csv" DeleteOrig="1" NewFilesOnly="1" SearchSubdirs="0" Unzip="0" RetryIfNoFiles="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefDelOldStateDays="1" UseDefStateCaching="1" UseDefRescanSecs="1" UDMxFi="1" UDMxBy="1" UseDefWinCopyFileAPI="1" ID="11"/>
        <Destination HostID="servername2" Type="Share" Path="Incoming" FileName="[OrigName]" UseOrigName="1" ForceDir="1" OverwriteOrig="1" UseRelativeSubdirs="1" Zip="0" UseDefRetryCount="1" UseDefRetryTimeoutSecs="1" UseDefWinCopyFileAPI="1" ID="12"/>
        <NextActions>
            <NextAction DoIfSuccess="0" DoIfFailure="1" DoIfNoAction="0" DoAfter="Task" Type="Email" HostID="12345" AddressTo="somebody@west.com" Subject="Subject" Message="Message"/>
        </NextActions>
    </Task>
</Tasks>

One option is to do this:

[xml]$xmlDoc = Get-Content .\test.xml
$xmlDoc.Tasks.Task | Where-Object {$_.Source.NewFilesOnly -eq '1'}

Which produces this output:

ID          : 1234
Name        : TaskName1
Active      : 1
Source      : Source
Destination : Destination
NextActions : NextActions

ID          : 1236
Name        : TaskName3
Active      : 1
Source      : Source
Destination : Destination
NextActions : NextActions

Another way to do it, is to use Select-XML with a XPath expression. If the size of the data you are processing is very large, you might get a better performance with this approach compared to Get-Content and type casting to xml.

$selectXmlSplat = @{
    'Path' = 'C:\Users\ps894840\Desktop\miccfg-export.xml'
    'XPath' = '//Source[@NewFilesOnly="1"]//ancestor::Task'
}
Select-Xml @selectXmlSplat | 
    Select-Object -ExpandProperty Node

After much digging I finally go it to work!

[XML]$XMLALL = Get-Content "C:\file\export.xml" 
$Tasks = $XMLALL.Exported.Tasks.Task

    Foreach ($item in $Tasks){

        $Name = $item.Name
        $NFO = $item.Source.NewFilesOnly

        Write-Host $Name
        Write-Host $NFO

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM