我正在執行一個 PS 腳本來讀取 xml 的內容,更新幾個標簽值并將內容存盤到多個 xml 檔案中。我能夠實作所有這些,但是創建的 xml 檔案沒有被傳遞到它的訊息傳遞佇列正確讀取。但是當我打開它并單擊保存而不對資料進行任何更改時,相同的 xml 檔案在佇列中作業。我比較了 2 個檔案 1 - 創建后和 2 - 打開相同檔案并單擊保存后,它們是相同的!我一生都無法弄清楚出了什么問題以及如何解決它。
如何以可讀格式創建輸出 xml 檔案?不確定當我在 xml 檔案上單擊“保存”時會發生什么變化。請幫忙。
輸入 CASH.XML:
<?xml version="1.0" encoding="UTF-8"?>
<ns:POSTransaction xmlns:ns="http://schema.xyz.com/Commerce/Customer/Transaction/v1">
<ns:tranHeader>
<ns:transactionId>96846836238236142669</ns:transactionId>
<ns:businessDateTime>2021-12-25T01:10:00</ns:businessDateTime>
<ns:emailId>[email protected]</ns:emailId>
</ns:tranHeader>
</ns:POSTransaction>
PS:
$log="H:\logs.txt"
[xml]$loadXML = Get-Content "H:\Q_This\CASH.XML"
try
{
$tranID = $loadXML.POSTransaction.tranHeader.transactionId.substring(17,3)
$tranIntID = [int]$tranID
$tranc = $loadXML.POSTransaction.tranHeader.transactionId.substring(0,17)
$uname = $loadXML.POSTransaction.tranHeader.emailId.substring(0,11)
$mailcnt = [int]$loadXML.POSTransaction.tranHeader.emailId.substring(11,3)
$mailend = $loadXML.POSTransaction.tranHeader.emailId.Split("@")[1]
for ($mailcnt; $mailcnt -lt 10; $mailcnt )
{
for ([int]$i =1; $i -le 5; $i )
{
$mailupd = ([string]($mailcnt 1)).PadLeft(3,'0')
$tranIntID = $tranIntID 1
$loadXML.POSTransaction.tranHeader.transactionId = $tranc [string]$tranIntID
$loadXML.POSTransaction.tranHeader.emailId = $uname $mailupd '@' $mailend
$fileName = "CASH_" $tranIntID "_" $mailupd ".XML"
$loadXML.Save("H:\Q_This\" $fileName)
}
}
}
catch
{
Write-Host $_.Exception.Message
Add-content $log -value ([string](Get-Date) ' ' $_.Exception.Message)
}
上面的代碼創建了 40 個輸出 xml 檔案:來自 Performancetest 003-010 @ymail.com 的每個 emailID 的 5 個事務檔案。但是,在我打開并單擊保存(沒有資料更改)之前,訊息佇列都沒有識別到??它。
uj5u.com熱心網友回復:
XML的API有編碼字符的支持在bult,如果給定的XML檔案的宣告指定一個在其XML宣告編碼明確(例如<?xml version="1.0" encoding="utf-8"?> ),該編碼尊重無論在讀取和寫入檔案。
因此,讀取和寫入 XML 檔案的可靠方法是使用專用的 XML API -在這種情況下是[xml]( System.Xml.XmlDocument)型別.Load()和.Save()方法 -而不是諸如Get-Content和Set-Content/ 之類的純文本處理 cmdletOut-File。
警告:
- 作為.NET 6.0 / 7.2的PowerShell的
.Save()方法出人意料地保存有明確的XML檔案encoding的屬性"utf-8"為UTF-8的檔案用BOM(位元組順序標記),這會導致問題的一些XML消費者(即使它不應該” t)。解決方法是洗掉expiicitencoding屬性(將其設定為$null);有關詳細資訊,請參閱此答案。
您后來的反饋表明您正在尋找ANSI編碼的輸出 XML 檔案,即您的目標是將輸入 XML 從 UTF-8轉碼為 ANSI。
以下是此類轉碼的簡化、自包含示例。它假定您系統的活動 ANSI 代碼頁是Windows-1252。
# In- and output files.
# IMPORTANT:
# Always use *full, file-system-native paths* when calling .NET methods.
$inFile = Join-Path $PWD.ProviderPath in.xml
$outFile = Join-Path $PWD.ProviderPath out.xml
# Create a UTF-8-encoded sample input file,
# for simplicity with plain-text processing.
# Note the non-ASCII character in the element text ('?')
'<?xml version="1.0" encoding="utf-8"?><foo>b?r</foo>' | Set-Content -Encoding utf8 $inFile
# Read the file using the XML-processing API provided via the [xml] type.
$xml = [xml]::new()
$xml.Load($inFile)
# Now change the character-encoding attribute to the desired new encoding.
# An XML declaration - if present - is always the *first child node*
# of the [xml] instance.
$xml.ChildNodes[0].encoding = 'windows-1252'
# Save the document.
# The .Save() method will automatically respect the specified encoding.
$xml.Save($outFile)
要驗證輸出檔案是否正確進行了 Windows-1252 編碼,請使用以下命令:
- PowerShell(核心) 7
# PowerShell (Core) defaults to UTF-8 in the absence of a BOM.
Get-Content -Encoding 1252 $outFile
- Windows PowerShell
# Windows PowerShell *defaults* to the
# system's active ANSI code page in the absence of a BOM.
Get-Content $outFile
您應該會看到以下輸出 - 請注意非 ASCII 字符的正確呈現?:
<?xml version="1.0" encoding="windows-1252"?>
<foo>b?r</foo>
注意:
- 不要不嘗試執行經轉碼的純文本處理,如使用的組合
Get-Content和Set-Content,因為有一個明確的encoding輸入XML attibute您將創建自相矛盾的XML檔案; 也就是說,檔案聲稱在其 XML 宣告中具有的編碼將與實際編碼不匹配。這可能并不總是很重要(如果消費者也執行純文本處理而不是正確的 XML 決議),但應避免僅用于概念清晰。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/395664.html
上一篇:匯入密碼-憑證
