Powershell XMLDocument บันทึกเป็น UTF-8 โดยไม่มี BOM
ฉันสร้างอ็อบเจ็กต์ XML ประเภท System.Xml.XmlDocument
$scheme.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False XmlDocument System.Xml.XmlNode
ฉันใช้วิธีบันทึก () เพื่อบันทึกลงในไฟล์
$scheme.save()
ซึ่งจะบันทึกไฟล์ในรูปแบบ UTF-8 ด้วย BOM BOM ทำให้เกิดปัญหากับสคริปต์อื่น ๆ ในบรรทัด
เมื่อเราเปิดไฟล์ XML ใน Notepad ++ และบันทึกเป็น UTF-8 (โดยไม่มี BOM) สคริปต์อื่น ๆ ในบรรทัดจะไม่มีปัญหา ดังนั้นฉันจึงถูกขอให้บันทึกสคริปต์โดยไม่มี BOM
เอกสาร MS สำหรับวิธีการบันทึกฯ :
ค่าของแอตทริบิวต์การเข้ารหัสนำมาจากคุณสมบัติ XmlDeclaration.Encoding ถ้า XmlDocument ไม่มี XmlDeclaration หรือถ้า XmlDeclaration ไม่มีแอ็ตทริบิวต์การเข้ารหัสเอกสารที่บันทึกไว้จะไม่มีอย่างใดอย่างหนึ่ง
เอกสาร MS ใน XmlDeclarationรายการเข้ารหัสคุณสมบัติของ UTF-8, UTF-16 และอื่น ๆ ไม่ได้กล่าวถึง BOM
XmlDeclaration มีคุณสมบัติการเข้ารหัสที่ทำให้ BOM หลุดออกไปหรือไม่
ปล. ลักษณะการทำงานนี้เหมือนกันใน Powershell 5 และ Powershell 7
คำตอบ
น่าเสียดายที่การมีอยู่อย่างชัดเจนของencoding="utf-8"
แอ็ตทริบิวต์ในการประกาศเอกสาร XML ทำให้. NET ไป.Save()
ยังเอกสารเป็นไฟล์ที่เข้ารหัส UTF-8 ด้วย BOMหากกำหนดพา ธ ไฟล์เป้าหมายซึ่งอาจทำให้เกิดปัญหาได้
คำขอให้เปลี่ยนแปลงนี้ถูกปฏิเสธเพราะกลัวว่าจะทำลายความเข้ากันได้ย้อนหลัง นี่คือคำร้องขอให้บันทึกพฤติกรรมอย่างน้อยที่สุด
ค่อนข้างแดกดันที่ขาดของencoding
แอตทริบิวต์ที่ทำให้เกิด.Save()
การสร้างไฟล์ UTF-8 เข้ารหัสโดยไม่ต้อง BOM
ดังนั้นวิธีแก้ไขง่ายๆคือการลบแอตทริบิวต์การเข้ารหัส[1] ; เช่น:
# Create a sample XML document:
$xmlDoc = [xml] '<?xml version="1.0" encoding="utf-8"?><foo>bar</foo>' # Remove the 'encoding' attribute from the declaration. # Without this, the .Save() method below would create a UTF-8 file *with* BOM. $xmlDoc.ChildNodes[0].Encoding = $null # Now, saving produces a UTf-8 file *without* a BOM. $xmlDoc.Save("$PWD/out.xml")
[1] สิ่งนี้ทำได้อย่างปลอดภัยเนื่องจากคำแนะนำ XML W3Cกำหนดให้ UTF-8 เป็นค่าเริ่มต้นอย่างมีประสิทธิภาพหากไม่มีทั้ง BOM และencoding
แอตทริบิวต์
ตามที่BACON อธิบายไว้ในความคิดเห็นค่าสตริงของEncoding
แอตทริบิวต์ในการประกาศ XML ไม่มีผลต่อการเข้ารหัสไฟล์ที่มีเอกสาร
คุณสามารถควบคุมโดยการสร้างอย่างใดอย่างหนึ่งStreamWriter
หรือXmlWriter
กับไม่ใช่ BOM UTF8Encoding
แล้วผ่านที่จะSave($writer)
:
$filename = Resolve-Path path\to\output.xml
# Create UTF8Encoding instance, sans BOM
$encoding = [System.Text.UTF8Encoding]::new($false)
# Create StreamWriter instance
$writer = [System.IO.StreamWriter]::new($filename, $false, $encoding)
# Save using (either) writer
$scheme.Save($writer)
# Dispose of writer
$writer.Dispose()
หรือใช้[XmlWriter]
:
# XmlWriter Example
$writer = [System.Xml.XmlWriter]::Create($filename, @{ Encoding = $encoding })
อาร์กิวเมนต์ที่สองคือ[XmlWriterSettings]อ็อบเจกต์ซึ่งเราสามารถควบคุมตัวเลือกการจัดรูปแบบได้มากขึ้นนอกเหนือจากการตั้งค่าการเข้ารหัสอย่างชัดเจน:
$settings = [System.Xml.XmlWriterSettings]@{ Encoding = $encoding
Indent = $true NewLineOnAttributes = $true
}
$writer = [System.Xml.XmlWriter]::Create($filename, $settings)
# <?xml version="1.0" encoding="utf-8"?>
# <Config>
# <Group
# name="PropertyGroup">
# <Property
# id="1"
# value="Foo" />
# <Property
# id="2"
# value="Bar"
# exclude="false" />
# </Group>
# </Config>