我正在为我正在玩的游戏编写一个PowerShell脚本来协助交易。
我创建了一个XML,我存储了我需要的所有信息。 XML看起来像:
<stuff>
<resource>
<type Name="Cotton" ID="0000">
<isDGV>1</isDGV>
<Storage>666</Storage>
<AvgBuyingPrice>
</AvgBuyingPrice>
<lastBuyingPrice>42</lastBuyingPrice>
<lowestBuyingPrice>
</lowestBuyingPrice>
<highestBuyingPrice>
</highestBuyingPrice>
<AvgSellingPrice>
</AvgSellingPrice>
<lastSellingPrice>
</lastSellingPrice>
<lowestSellingPrice>
</lowestSellingPrice>
<highestSellingPrice>
</highestSellingPrice>
<BuyingPricesHistory-Last42>
<price>62</price>
<price>42</price>
</BuyingPricesHistory-Last42>
<SellingPricesHistory-Last42>
<price>
</price>
</SellingPricesHistory-Last42>
<TownsProducedIn>
<town>Sampletown</town>
</TownsProducedIn>
<TownsNeededIn>
</TownsNeededIn>
</type>
<type Name="Spices" ID="0001">
<isDGV>0</isDGV>
.
.
</resource>
</stuff>
现在我想有可能&#34;清洁&#34;特定资源的所有子节点。因此,例如<Storage>666</Storage>
再次成为<Storage></Storage>
。
这是我认为应该起作用的,但显然,它并不那么容易?
(代码不完整,但$XMLfile
加载得很好,因为它也用于显示资源的值。saveXML
函数也可以工作)
$target = $XMLfile.stuff.resource.SelectNodes('type/child::*') | where { $_.Name -eq "$resName" -and $_.ID -eq $ID }
foreach ($Child in $target)
{
$Child.InnerText = ""
}
saveXML $xmlFilePathAndName
更糟糕的是:我没有从该代码中收到任何错误消息: - )
答案 0 :(得分:1)
问题是,您的SelectNodes()
会返回 type
的子元素,而Name
和ID
属性位于{{ 1}}父元素级别。因此,替代type
过滤器未找到与属性值标准匹配的任何元素。
您可以使用XPath按其属性过滤where ...
元素,然后在一个表达式中返回子元素,如下所示:
type
请注意,$target = $XMLfile.stuff.resource.SelectNodes("type[@Name='$resName' and @ID='$ID']/*")
是XPath中的默认轴,因此当您删除它时,只留下路径分隔符child::
时,引擎将暗示您希望在此处使用默认轴。 / p>
答案 1 :(得分:0)
考虑一个XSLT解决方案,这是一种用于转换XML文档的专用声明性编程语言。实际上,XSLT脚本是格式良好的XML文件!像大多数通用语言(C#,Java,Perl,PHP,Python,VB)一样,命令行解释器(如PowerShell和Bash)可以运行XSLT。当然,他们也可以使用参数调用外部处理器(Saxon and Xalan)和上述语言。
XSLT 脚本(另存为外部.xsl文件;可移植到其他语言/平台)
<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>
<!-- Re-Write for Empty Storage Element -->
<xsl:template match="Storage">
<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;
命令行
PS > powershell -File PowerShellScript.ps1 Input.xml, XSLTScript.xsl, Output.xml