[英]Analyse XML file with powershell script
我有一個 xml 日志文件。 該文件如下所示:
<Transaction name='0' id='1'>
<Response>Warning</Response>
<Statistic mode='Element'>
<Information>0</Information>
<Warning>0</Warning>
<Error>0</Error>
</Statistic>
<Messages>
<Message state='Warning'>Personal-Nr.: 12345, Tom Test</Message>
<Message state='Warning'>This is a warning message 1</Message>
<Message state='Warning'>This is a warning message 2</Message>
<Message state='Warning'>This is a warning message 3</Message>
<Message state='Warning'>This is a warning message 4</Message>
</Messages>
</Transaction>
這種模式重復大約 900 次,有時會有更多或更少的消息。 現在我只想獲取發生<Response>Error</Response>
的所有事務。
所以我在 Powershell 中編寫了這段代碼:
## parsing xml file and opening inner node
Select-Xml -Path C:\Users\user\path\path\file.xml -XPath '/Paths/Task/Transaction' | ForEach-Object { $_.Node.InnerXML }
## looping through Response set with include="Error"
$_.Node.InnerXML | Where-Object Response -eq 'Error' | ForEach-Object { $_.Messages }
echo $_.Messages
但我得到的唯一數據是所有交易,無論響應是Warning
還是Error
。 更進一步,我是否只留下Select-Xml
行並刪除其余行也沒關系。 結果總是一樣的。 我總是得到所有的回應。
所以我的問題是:我如何才能只獲得 Response 為Error
的交易?
額外問題:是否有可能只將每個Error
事務的第一條消息行作為輸出? 這樣我就有了一個錯誤交易中的所有Personal-Nr
的列表?
非常感謝
您發布的語句目前完全獨立 - 第一個輸出所有交易節點的文本編碼,第二個和第三個根本不做任何事情,因為此時$_
不再具有分配給它的值.
要正確“連接”它們,您必須將過濾邏輯放在第一個ForEach-Object
塊中,例如:
Select-Xml ... |ForEach-Object {
if($_.Node.Response -eq 'Error'){ $_.Messages }
}
...或將每個步驟的輸出存儲在臨時變量中,例如:
$allTransactions = Select-Xml ... -XPath '//Transaction'
$allTransactions |ForEach-Object {
if($_.Node.Response -eq 'Error'){ $_.Messages }
}
我應該指出ForEach-Object { if(...){ $_ } }
有點反模式,除非您的代碼具有更復雜的副作用 - 更慣用的解決方案是調用Where-Object
cmdlet過濾來自Select-Xml
的輸出:
$allTransactions |Where-Object {
$_.Node.Response -eq 'Error'
} |ForEach-Object Messages
雖然這些建議可能會解決您的問題,但我強烈建議您不要這樣做- XPath 比您當前使用它的功能強大得多 :)
如何僅獲取響應為“錯誤”的事務?
我建議通過使用帶有Select-Xml
的更准確的 XPath 表達式來簡化您的代碼——它可以准確地查找您想要的內容:
Select-Xml -Path C:\Users\user\path\path\file.xml -XPath '/Paths/Task/Transaction[Response = "Error"]'
是否有可能只將每個“錯誤”事務的第一個消息行作為輸出? 這樣我就有了一個錯誤交易中所有“Personal-Nr”的列表?
確定的事!
再一次,最簡單的方法是修改 XPath 表達式,這次只解析符合上述條件的<Transaction>
下的第一個<Message>
節點:
# beware that index selectors in XPath start at 1, not 0
//Transaction[Response = "Warning"]/Messages/Message[1]
但這還不是全部! XPath 有幾個有用的功能——所以我們可以更深入一步,讓XPath
也為我們提取和解碼消息文本!
//Transaction[Response = "Warning"]/Messages/Message[1]/text()
這將導致Select-Xml
返回一個由XmlText
實例組成的節點集,您可以將其直接轉換為字符串以獲取原始字符串內容。
將其與Select-Xml
重新組合在一起,您最終會得到如下結果:
$filePath = 'C:\Users\user\path\path\file.xml'
$xPath = '//Transaction[Response = "Warning"]/Messages/Message[1]/text()'
$messages = Select-Xml -Path $filePath -XPath $xPath |ForEach-Object ToString
$messages
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.