值函数的XML函数?

时间:2016-03-20 11:39:30

标签: xml powershell call-by-value

我有一个函数返回一个包含各种键的哈希表,其中一个键是XML。我还有一些代码用于在返回之前修改此XML。但是,我最初看起来是管道污染问题,但我已将其与XML替换代码隔离开来。

所以,最初我使用$result.xml直接使用返回哈希中的键完成了我的所有XML替换。但是,我已经改变了代码,使用了一个单独的变量:

$revisedXml = $result.xml
$oldnode = $revisedXml.selectSingleNode("/Definitions/InstallTypes/InstallType[@id='$supersedes']")
$newnode = $temp.xml.selectSingleNode("/Definitions/InstallTypes/InstallType[@id='$supersedes']")
$importNode = $revisedXml.ImportNode($newnode, $true)
$oldnode.ParentNode.AppendChild($importNode)
$oldnode.ParentNode.RemoveChild($oldnode)

但是,最后两行中的任何一行都会导致$return哈希爆炸。这让我想到我认为我记得XML是通过引用而不是通过值来记住的,所以我真正在做的是直接访问XML,只是通过一个新的指针,而我正在改变的东西会炸毁整个哈希表变量也引用了XML。这听起来是对的吗,还是我已经走错了路?

另外,也许是相关的。我最终要做的是在$result.xml和另一个$temp.xml(从不同文件加载)中搜索特定节点,如果找到,请将$result中的一个替换为来自$temp。我尝试使用ReplaceChild(),但这似乎不起作用,可能是PowerShell 2.0问题。

那么,有了这两位数据,是否有更好的方法来修改XML,有没有办法让它能够正常地通过值传递XML? FWIW,我正在重构以避免我成功使用的全局XML变量。我通常不喜欢全局变量,但也许这是我必须使用它们的一种情况?

修改 因此,试图孤立问题,并遇到新问题。在这里,我尝试在函数中创建两个XML变量,将一个变量中的节点替换为另一个变量,并将其传递回函数,然后写入控制台以验证结果是否正确(差异是SilentModeID应该是9)。问题是这里的两个字符串不起作用。尝试使用单引号,但仍然抛出错误。在我真正的代码中并不是苹果到苹果我不是在这里使用字符串,我正在从文件中读取XML,但出于讨论的目的,它似乎是更好的方法。所以,第一个新问题,我在这里用字符串做错了什么?一旦它工作,我们可以看到是否以相同的方式将XML传回。

function Write-PxXmlToConsole ($xml) {
    $stringWriter = New-Object System.IO.StringWriter
    $xmlWriter = New-Object System.Xml.XmlTextWriter $stringWriter
    $xmlWriter.Formatting = "indented"
    $xml.WriteTo($xmlWriter)
    $xmlWriter.Flush()
    $stringWriter.Flush()
    Write-Host $stringWriter.ToString()
}


function Import-PxXml {

$result = @{
    success = $true
    xml = $null
    log = $null
}

[xml]$assets = @"
<?xml version="1.0"?>
<Definitions>
<InstallTypes>
<InstallType id="deployment">
<SilentModeID>1</SilentModeID>
</InstallTypes>
</InstallType>
</Definitions>
"@

[xml]$newAssets = @"
<?xml version="1.0"?>
<Definitions>
<InstallTypes>
<InstallType id="deployment">
<SilentModeID>9</SilentModeID>
</InstallType>
</InstallTypes>
</Definitions>
"@

$nodeName = 'deployment'

$oldnode = $assets.selectSingleNode("/Definitions/InstallTypes/InstallType[@id='$nodeName']")
$newnode = $newAssets.selectSingleNode("/Definitions/InstallTypes/InstallType[@id='$nodeName']")
$importNode = $assets.ImportNode($newnode, $true)

$oldnode.ParentNode.AppendChild($importNode)
$oldnode.ParentNode.RemoveChild($oldnode)

$result.xml = $assets
$result.log = 'Crossed Fingers'

return $result
}


$test = Import-PxXml
Write-PxXmlToConsole $test.xml

1 个答案:

答案 0 :(得分:0)

RemoveChild()AppendChild()方法返回有问题的子节点,污染您的输出。

取消输出,你会没事的:

$null = $oldnode.ParentNode.AppendChild($importNode)
$null = $oldnode.ParentNode.RemoveChild($oldnode)