Массовое переименование файлов XML на основе значения узла - PullRequest
0 голосов
/ 09 мая 2019

Я пытался подготовить сценарий powershell, который переименовал бы все файлы XML в значение одного из узлов XML:

$items = Get-ChildItem "C:\test\" -Filter *.xml
foreach ($item in $items) {
    $x = New-Object -TypeName 'System.XML.XMLDocument'
    $x.Load($item.FullName)
    $OutputFileName = $x.SelectSingleNode("//CreationDate").InnerText
    $OutputFileName = $OutputFileName -replace "-", "_"
    $OutputFileName = $OutputFileName -replace ":", "_"
    $OutputFileName = $OutputFileName -replace "T", "_"
    Rename-Item $item.Fullname -NewName "$OutputFileName.xml"
}

У меня проблема в том, что $x всегда пусто,Кажется, что я не могу правильно получить значение узла XML.

Структура XML (имейте в виду, что узел <ActualStartDate> изменяется между файлами, остальные имена совпадают)

<?xml version="1.0" encoding="utf-8"?>
<Request xmlns="link">
    <ActualStartDate>
        <TypeCode>0400</TypeCode>
        <VerNumber>2</VerNumber>
        <CreationDate>2012-01-31T14:33:35</CreationDate>
    </ActualStartDate>
</Request>

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

Большое спасибо всем, кто помог.

В конце концов, я обнаружил, что проблема заключалась в том, что у меня было пространство имен в файле XML со ссылкой, которая не работала.Я не привел в пример пространство имен, которое, как я не знал, было важно в этом случае, извините за это.

Помещение в сценарий дополнительных 2 строк, игнорирующих это определение пространства имен, решило проблему для меня:

$xml = New-Object xml
$xml = ([String](Get-Content "file.xml") -replace 'xmlns.*CONFIG">','>' )

(Спасибо: http://www.kv0.org/blog/2012/05/04/ignore-xml-namespaces-in-powershell/)

0 голосов
/ 09 мая 2019

Ваш код работает с данным примером XML, но проблема, с которой вы столкнулись, может быть связана с тем, что при использовании XPath учитывается регистр. Возможно, тег CreationDate называется creationDate в некоторых других файлах, или он может вообще отсутствовать.

Возможно, попробуйте это:

Get-ChildItem 'C:\test' -Filter *.xml -File | ForEach-Object {
    [xml]$x = $_ | Get-Content -Encoding UTF8

    # get the value of tag CreationDate using XPath (case Sensitive)
    # $OutputFileName = $x.SelectSingleNode("//CreationDate").InnerText
    # or by following the properties of the xml object (case-Insensitive)
    $outputFileName = @($x.Request.ActualStartDate.CreationDate)[0]

    if ([string]::IsNullOrWhiteSpace($outputFileName)) {
        Write-Warning "Could not find value for CreationDate in file '$($_.FullName)'" 
    }
    else {
        $OutputFileName = $OutputFileName -replace '[-:T]', '_'

        Write-Host "Renaming file $($_.FullName) to $OutputFileName.xml"
        $_ | Rename-Item -NewName "$OutputFileName.xml" -Force
    }
 }
...