根据子元素的值找到一个主要元素,然后更改其他子元素的值

时间:2019-03-08 13:55:07

标签: xml powershell

我有一个具有以下结构的xml文件:

<PARENT>
    <LIBRARY>
        <BOOKS>
            <BOOK>
                <BOOK_DATA>
                    <BOOK_TITLE>HOBBIT</BOOK_TITLE>
                </BOOK_DATA>
                <STATUS>NotRead</STATUS>
            </BOOK>
            <BOOK>
                <BOOK_DATA>
                    <BOOK_TITLE>LOTR_FOTR</BOOK_TITLE>
                </BOOK_DATA>
                <STATUS>NotRead</STATUS>
            </BOOK>
            <BOOK>
                <BOOK_DATA>
                    <BOOK_TITLE>LOTR_TT</BOOK_TITLE>
                </BOOK_DATA>
                <STATUS>NotRead</STATUS>
            </BOOK>
            <BOOK>
                <BOOK_DATA>
                    <BOOK_TITLE>LOTR_ROTK</BOOK_TITLE>
                </BOOK_DATA>
                <STATUS>NotRead</STATUS>
            </BOOK>
        </BOOKS>
    </LIBRARY>
</PARENT>

使用powershell脚本,我需要找到包含$ BookTitle的BOOK元素,然后将STATUS元素的值更改为$ NewStatus

示例:

$ BookTitle = LOTR_TT

$ NewStatus =读取

发现:

        <BOOK>
            <BOOK_DATA>
                <BOOK_TITLE>LOTR_TT</BOOK_TITLE>
            </BOOK_DATA>
            <STATUS>NotRead</STATUS>
        </BOOK>

并将其更改为:

        <BOOK>
            <BOOK_DATA>
                <BOOK_TITLE>LOTR_TT</BOOK_TITLE>
            </BOOK_DATA>
            <STATUS>Read</STATUS>
        </BOOK>

我在StatusChanger.ps1中具有以下内容,但未产生预期的结果:

param ($BookTitle = LOTR_TT)
param ($NewStatus = Read)
param ($FilePath = C:\file.xml)

#Open the file
[xml]$xml = Get-Content -Path $FilePath

$xml.parent.library.books.book | where { $_.book_data.book_title -like "$BookTitle" } | ForEach {
$_.STATUS = '$NewStatus'
}

#Save the updated file
$xml.Save($FilePath)

3 个答案:

答案 0 :(得分:0)

我建议按Tagname查找元素。然后,您可以在层次结构中上移以访问“书”的相应状态。

然后很容易设置状态。

$foundedElement = $test.GetElementsByTagName("BOOK_TITLE") |Where-Object {$_."#text" -eq $BookTitle}

$foundedElement.ParentNode.ParentNode.STATUS = $NewStatus

$test.Save($fileName)

答案 1 :(得分:0)

我建议使用tblImagesSubmitted来解决此问题:

$query = "SELECT `fldImageID` FROM `tblImage` ORDER BY `fldImageID` DESC LIMIT 1";

这里的重要部分是过滤器:

XPath

这将从匹配过滤器[xml]$xml = ' ... ' $bookTitle = 'LOTR_TT' $newStatus = 'Read' $node = $xml.SelectSingleNode("//BOOK[BOOK_DATA/BOOK_TITLE='$bookTitle']/STATUS") $node.'#text' = $newStatus 的书中选择//BOOK[BOOK_DATA/BOOK_TITLE='$bookTitle']/STATUS 节点,并且powershell将STATUS公开为BOOK_TITLE='$bookTitle'属性。


在示例脚本中使用:

InnerText

或者,如果要查找包含要更改为读取的字符串的所有节点,则可以执行以下操作:

#text

答案 2 :(得分:0)

据我所知,您的代码中有两个错误:

  1. 您应该引用$BookTitle$NewStatus的值,以便它们成为
    $BookTitle = 'LOTR_TT'$NewStatus = 'Read'
  2. 您单引号为:$_.STATUS = '$NewStatus',然后将STATUS设置为“ $ NewStatus”的文字值。删除这些引号以插入变量的

    $_.STATUS = $NewStatus

那之后如果对我来说还行。