2016-03-20 15 views
0

Biri XML olan, çeşitli anahtarlarla bir karma tablo döndüren bir işlev var. Ayrıca bu XML'i geri göndermeden önce gözden geçirmeyi amaçlayan bir kod da var. Bununla birlikte, ilk olarak boru hattı kirliliği sorunları olarak göründüğüme sahibim, ancak bunu XML değiştirme koduna ayırdım.XML işlevi değer sorununa göre mi?

Bu nedenle, başlangıçta tüm XML değiştirmeyi, $result.xml kullanarak dönüş karesindeki anahtarla doğrudan yaptım.

$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) 

Ancak, bu son iki satırlardan biri havaya uçurmak için $return karma neden şudur: Ancak, ben bu yana böyle ayrı bir değişken kullanarak kodu değişti. Bence, XML ile ilgili bir değer hatırladığımı düşünüyorum, bu yüzden gerçekten yaptığım şey doğrudan XML'e erişiyor, sadece yeni bir işaretçi ile, ve bir şekilde değiştirdiğim şey, hash tablosu değişkeninin tamamını havaya uçuruyor. XML de başvurur. Bu doğru mu, yoksa yanlış bir yola mı gidiyorum? Ayrıca, ve belki de ilgili olabilir. Sonunda yaptığım şey, $result.xml ve farklı bir $temp.xml (farklı dosyalardan yüklenen) içinde belirli bir düğümü arar ve bulunursa, 'daki kodu $temp ile değiştirin. ReplaceChild() kullanmayı denedim, ancak bu çalışmıyor, belki de bir PowerShell 2.0 sorunu görünüyor.

Yani, bu iki veri biti ile, XML'i gözden geçirmenin daha iyi bir yolu var mıdır ve XML'i uygun bir şekilde değerden geçiren bir işlevle çalışmanın bir yolu var mı? FWIW, başarıyla kullandığım global XML değişkeninden kaçınmak için tekrar yapıyorum. Genel olarak global değişkenleri sevmiyorum ama belki de bunları kullanmak zorunda olduğum bir durum mu?

DÜZENLEME: Yani, sorunun nedenini tespit için çalışıyor ve yeni sorunları çalıştıran. Burada fonksiyonda iki XML değişkeni yaratmaya çalışıyorum, bir düğümün bir değişkenden diğerinden düğümü ile değiştirin ve işlevin dışına geri aktarın, ardından sonucun doğru olduğunu doğrulamak için konsola yazın (fark SilentModeID olmalıdır. 9). Sorun burada iki dizge çalışmıyor. Tek tırnak ile de denedim, ancak yine de hatalar atıyor. Elmalarıma değil, gerçek kodumdaki elmalara da değil, burada dizeleri kullanmıyorum, dosyaları XML'den okuyorum ama tartışmanın amaçları için daha iyi bir yol gibi görünüyordu. Öyleyse, ilk yeni soru, burada dizelerle ne yapıyorum? Çalışmaya başladıktan sonra, XML’i geri göndermenin aynı şekilde kırılıp kırılmadığını görebiliriz.

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

Ne şekilde "bu son iki satırlardan biri havaya uçurma $ dönüş karma neden olur"? –

+0

Bozuk bir boru hattı sorununun görünümünü verir. Eğer fonksiyonun sonunda $ dönüşü ile yineliyorsam, "doğru" görünüyor, fakat fonksiyonu alan değişken ile yineleniyorsa, tek bir anahtar, isimsiz ve değeri yokmuş gibi görünüyor. Ama .count ile 3 anahtar, işlevdeki $ return hash olan dört anahtar değil. Fonksiyondaki bu iki satırı hatırlayın ve her şey çağrı kodunda çalışır. Ama tabii ki XML değişmez, bu yüzden kullanışlı bir kod değil, sadece "çalışma" kodu. – Gordon

+1

Bir sürü başka kod var, bu yüzden yüzlerce yabancı çizgi olmadan yararlı bir örnek yayınlamak için sorunu yalıtmaya çalışıyorum. Ama bu kendi içinde bir sürü zaman alıyor. – Gordon

cevap

0

RemoveChild() ve AppendChild() yöntemi çıkışını kirletmeden, söz konusu alt düğüm döndürür.

çıkışını bastırmak ve iyi olacak:

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

Oh, huzzah! Sonuçta kirli boru hattı! Bazen gerçekten de, boru hattı davranışını devre dışı bırakmayı tercih etmenin bir yolu olsaydı, sonra gerektiğinde geri dönmesini isterdim. Bu arada, yönlendirme için teşekkürler! ;) – Gordon

+0

Evet, şu anda ve tekrar olarak kesinlikle bir 'dönüş' için uzun, ama her şeye sahip olamazsınız :) –

+0

True Dat. Ve gerçekten sorunu unuttum PowerShell'in İlk Kuralı: Muhtemelen Pipeline Pollution Bundan sonra, bir sorun varsa ve bunu bir satıra ayırabilirseniz, ilk sorun giderme adımım sonuna> $ null atmaktır ve ne olduğunu görün. – Gordon