我真的很难在PowerShell中操作一些我需要作为正文发送回Web服务的XML。任何人都可以帮助我按照需要的方式获取XML吗?
<?xml version="1.0" encoding="UTF-8"?>
<EdgeGateway>
<Configuration>
<GatewayInterfaces>
<GatewayInterface>
<InterfaceType>uplink</InterfaceType>
<SubnetParticipation>
<Gateway>1.2.3.4</Gateway>
<Netmask>255.255.255.240</Netmask>
<IpAddress>1.2.3.5</IpAddress>
# Missing the IpRange XML section - defined below
<UseForDefaultRoute>true</UseForDefaultRoute>
</SubnetParticipation>
<UseForDefaultRoute>true</UseForDefaultRoute>
</GatewayInterface>
</GatewayInterfaces>
</Configuration>
</EdgeGateway>
需要成为:
<?xml version="1.0" encoding="UTF-8"?>
<EdgeGateway>
<Configuration>
<GatewayInterfaces>
<GatewayInterface>
<InterfaceType>uplink</InterfaceType>
<SubnetParticipation>
<Gateway>1.2.3.4</Gateway>
<Netmask>255.255.255.240</Netmask>
<IpAddress>1.2.3.5</IpAddress>
# New Content added here
<IpRanges>
<IpRange>
<StartAddress>1.2.3.5</StartAddress>
<EndAddress>1.2.3.5</EndAddress>
<IpRange>
</IpRanges>
# End of new content
<UseForDefaultRoute>true</UseForDefaultRoute>
</SubnetParticipation>
<UseForDefaultRoute>true</UseForDefaultRoute>
</GatewayInterface>
</GatewayInterfaces>
</Configuration>
</EdgeGateway>
到目前为止,我已经能够为新内容创建新的XML节点/元素,但我无法将其插入到正确的位置。我可以使用AppendChild()
方法,但它会将内容放在<UseForDefaultRoute>
部分之后 - 而不是之前。
我已尝试InsertBefore()
和InsertAfter()
,但它只是不想工作。
最后,当我执行AppendChild()
方法时,我还得到了一些我不期待的额外文本,关于xmlns的内容?
<IpRanges xmlns=""><IpRange><StartAddress>1.2.3.5</StartAddress><EndAddress>1.2.3.5</EndAddress></IpRange></IpRanges>
这是我设法放在一起的,请记住它已经破碎了:(
# load XML file
[xml]$doc = $response
# create node <StartAddress>
$startNode = $doc.CreateNode('element', 'StartAddress', '')
$start = $doc.CreateTextNode('1.2.3.5')
$startNode.AppendChild($start) | Out-Null
# create node <EndAddress>
$endNode = $doc.CreateNode('element', 'EndAddress', '')
$end = $doc.CreateTextNode('1.2.3.5')
$endNode.AppendChild($end) | Out-Null
# create node <IpRange> and append child nodes <StartAddress> and <EndAddress>
$ipRange = $doc.CreateNode('element', 'IpRange', '')
$ipRange.AppendChild($startNode) | Out-Null
$ipRange.AppendChild($endNode) | Out-Null
# create node <IpRanges> and append child nodes <IpRange>
$ipRanges = $doc.CreateNode('element', 'IpRanges', '')
$ipRanges.AppendChild($ipRange) | Out-Null
# append node <IpRanges> to node <SubnetParticipation>
$subnetParticpation = $doc.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[1].SubnetParticipation.AppendChild($ipRanges)
...根据Ansgar的建议,这是我尝试使用命名空间。 (碎)
[xml]$fragment = "<dummy xmlns:xsi='http://www.vmware.com/vcloud/v1.5'><IpRanges>$($ipRanges.InnerXml)</IpRanges></dummy>"
# $fragment.InnerXml ..returns..
# <dummy xmlns:xsi="http://www.vmware.com/vcloud/v1.5"><IpRanges><IpRange><StartAddress>185.39.247.98</StartAddress><EndAddress>185.39.247.98</EndAddress></IpRange></IpRanges></dummy>
# $body is the full XML Document I want to paste into
[xml]$xml = $body
$nsm = New-Object Xml.XmlNamespaceManager $xml.NameTable
$nsm.AddNamespace('xsi', $xml.NamespaceURI)
$node = $xml.ImportNode($fragment.DocumentElement.IpRanges, $true)
$subnetPart = $xml.SelectSingleNode("//IpAddress[text()='185.39.247.98']", $nsm)
$subnetPart
# returns nothing
答案 0 :(得分:1)
您可以在其他节点之后插入新节点,如下所示:
$node = $doc.SelectSingleNode("//IpAddress[text()='1.2.3.5']")
$node.ParentNode.InsertAfter($ipRanges, $node)
答案 1 :(得分:0)
考虑XSLT,这是一种特殊用途,符合W3C标准的语言,旨在将XML文件转换为其他XML,HTML甚至文本格式。 PowerShell可以调用内置的XslCompiledTransform类,传入源文件,xslt脚本和输出文件的参数。
XSLT (使用Identity Transform按原样复制并更新SubnetParticipation节点)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SubnetParticipation">
<xsl:copy>
<xsl:apply-templates />
<IpRanges>
<IpRange>
<StartAddress>1.2.3.5</StartAddress>
<EndAddress>1.2.3.5</EndAddress>
</IpRange>
</IpRanges>
</xsl:copy>
</xsl:template>
</xsl:transform>
<强>的PowerShell 强>
param ($xml, $xsl, $output)
if (-not $xml -or -not $xsl -or -not $output) {
Write-Host "& .\xslt.ps1 [-xml] xml-input [-xsl] xsl-input [-output] transform-output"
exit;
}
trap [Exception]{
Write-Host $_.Exception;
}
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load($xsl);
$xslt.Transform($xml, $output);
Write-Host "generated" $output;
命令行调用(或批处理脚本调用)
Powershell.exe -File "C:\Path\To\PowerShell\Script.ps1"
"C:\Path\To\Source.xml" "C:\Path\To\Transform.xsl" "C:\Path\To\Output.xml"
<强>输出强>
<?xml version="1.0" encoding="utf-8"?>
<EdgeGateway>
<Configuration>
<GatewayInterfaces>
<GatewayInterface>
<InterfaceType>uplink</InterfaceType>
<SubnetParticipation>
<Gateway>1.2.3.4</Gateway>
<Netmask>255.255.255.240</Netmask>
<IpAddress>1.2.3.5</IpAddress>
<UseForDefaultRoute>true</UseForDefaultRoute>
<IpRanges>
<IpRange>
<StartAddress>1.2.3.5</StartAddress>
<EndAddress>1.2.3.5</EndAddress>
</IpRange>
</IpRanges>
</SubnetParticipation>
<UseForDefaultRoute>true</UseForDefaultRoute>
</GatewayInterface>
</GatewayInterfaces>
</Configuration>
</EdgeGateway>