2016-03-19 30 views
0

私は取引を支援するためにプレイしているゲーム用のPowerShellスクリプトを記述しています。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> 

:XMLは次のようになります。たとえば<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 

さらに悪いことに:私はすべてのエラーメッセージを得ることはありませんNameID属性がtype親要素のレベルでありながら、そのコード:-)

答えて

1

のうちの問題は、typeのごSelectNodes()戻り子要素ということでした。そのため、サブステップのwhere ...フィルタでは、属性値の基準に一致する要素が見つかりませんでした。

あなたがそうのように、その属性によってtype要素をフィルタリングするためにXPathを使用して、子要素を返し、1式のすべてのことができます

child::は、XPathのデフォルトの軸である、そうすることを

$target = $XMLfile.stuff.resource.SelectNodes("type[@Name='$resName' and @ID='$ID']/*") 

お知らせそれを削除し、パスセパレータ/だけを残すと、エンジンはデフォルトの軸をここで使用することを意味します。

+0

ありがとうございました。あなたのソリューションは完璧に動作します。 XMLを扱うさまざまな方法は、私にとってはまだ非常に混乱しています。 Regexに似ています。 – StUffz

0

XMLドキュメントを変換するために設計された特別目的の宣言型プログラミング言語であるXSLTソリューションを考えてみましょう。実際、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 
関連する問題