使用powershell循环遍历XML文件,并将一个字段合并到另一个字段中

时间:2018-03-01 12:35:21

标签: xml powershell

我有一个XMLTV文件,我想将子标题(剧集名称)节点添加到每个程序的 desc 列表,以便 desc 标记看起来像这样 - >

<desc lang=en>Episode Title: Episode description.</desc>

这是我所拥有的XML文件的摘录:

<?xml version="1.0"?>
<tv>
    <programme start="20180228110000 +0000" stop="20180228120000 +0000" channel="21558">
        <title lang="en">Forged in Fire</title>
        <sub-title lang="en">Talwar</sub-title>
        <desc lang="en">With just five days to recreate the sacred but lethal Talwar sword, which smith will defy all odds to claim the title of Forged in Fire Champion and a 10,000 dollar prize?</desc>
        <credits>
            <producer>Tim Healy</producer>
            <presenter>Wil Willis</presenter>
        </credits>
        <category>Reality</category>
        <category>Series</category>
        <category>series</category>
        <episode-num system="xmltv_ns">3.6.</episode-num>
        <episode-num system="dd_progid">EP023535090040</episode-num>
        <previously-shown start="20170516120000 +0000"/>
        <rating system="Australian Classification Board">
            <value>PG</value>
        </rating>
        <rating system="Canadian Parental Rating">
            <value>PG</value>
        </rating>
        <rating system="R&#xE9;gie du cin&#xE9;ma">
            <value>G</value>
        </rating>
        <rating system="Freiwillige Selbstkontrolle der Filmwirtschaft">
            <value>12</value>
        </rating>
        <rating system="USA Parental Rating">
            <value>TVPG</value>
        </rating>
    </programme>
</tv>

我正在尝试使用Powershell,以便我可以将它设置为每晚的预定任务,到目前为止我的是:

$in = 'C:\Downloader\XMLTV\Guide\SchedulesDirect\guide.xml'
$out = 'C:\Downloader\XMLTV\Guide\SchedulesDirect\guide1.xml'
$xml = (Get-Content $in)

ForEach ($Node in $in.tv.programme) {
    $in.tv.programme.desc = $in.'tv.programme.sub-title' + $in.tv.programme.desc
    Set-Content $out
}

即使在这里做了一些事情之后,我似乎也没有好运,任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

您需要将文件读作XmlDocument才能循环节点。循环还必须循环xml对象中的节点(而不是输入路径)并引用scriptblock内的当前节点。尝试:

$in = 'C:\Downloader\XMLTV\Guide\SchedulesDirect\guide.xml'
$out = 'C:\Downloader\XMLTV\Guide\SchedulesDirect\guide1.xml'

#You should parse the file as an XmlDocument-object
$xml = [xml](Get-Content $in)

#Template-node for desc
$DescExample = $xml.SelectSingleNode('//programme/desc').Clone()
#The xml-picture in comments didn't show lang="en" on all programme-nodes, so new desc-nodes are created without
$DescExample.RemoveAllAttributes()

#Loop programme-nodes in the XmlDocument-object
ForEach ($Node in $xml.tv.programme) {

    if($Node.'sub-title') {
        if($Node.desc) {
            #Set desc for each node to "Sub-Title: Desc"
            $Node.desc.InnerText = "{0}: {1}" -f $Node."sub-title".InnerText, $Node.desc.InnerText
        } else {
            #Desc-element missing. Will create one
            $newdesc = $DescExample.Clone()
            $newdesc.InnerText = $Node.'sub-title'.InnerText
            $Node.AppendChild($newdesc) > $nul
        }
    }    
}

#Save document when all nodes are modified, not inside the loop
$xml.Save($out)