XML 值函数问题?

XML function by value issue?

我有一个函数,它 return 是一个散列 table,其中包含各种键,其中之一是 XML。我还有一些代码旨在在 return 之前修改此 XML。但是,我遇到的问题起初似乎是管道污染问题,但我已将其隔离到 XML 替换代码中。

因此,最初我使用 $result.xml 直接用 return 散列中的密钥完成所有 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,只是通过一个新指针,以及我正在以某种方式改变的东西炸毁整个散列 table 变量,该变量也引用 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

RemoveChild()AppendChild() 方法 returns 有问题的子节点,污染了你的输出。

抑制输出,你会没事的:

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