Powershell XMLDocument는 BOM없이 UTF-8로 저장
System.Xml.XmlDocument 형식의 XML 개체를 만들었습니다.
$scheme.gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False XmlDocument System.Xml.XmlNode
save () 메서드를 사용하여 파일에 저장합니다.
$scheme.save()
이렇게하면 BOM이있는 UTF-8 형식으로 파일이 저장됩니다. BOM은 다른 스크립트에 문제를 일으 킵니다.
Notepad ++에서 XML 파일을 열고이를 BOM없이 UTF-8로 저장하면 다른 스크립트에는 문제가 없습니다. 그래서 BOM없이 스크립트를 저장하라는 요청을 받았습니다.
저장 방법에 대한 MS의 문서 상태 :
인코딩 특성의 값은 XmlDeclaration.Encoding 속성에서 가져옵니다. XmlDocument에 XmlDeclaration이 없거나 XmlDeclaration에 인코딩 특성이없는 경우 저장된 문서에도 인코딩 특성이 없습니다.
XmlDeclaration에 대한 MS 문서 에는 UTF-8, UTF-16 등의 인코딩 속성이 나열되어 있습니다. BOM은 언급하지 않습니다.
XmlDeclaration에 BOM을 제거하는 인코딩 속성이 있습니까?
추신. 이 동작은 Powershell 5 및 Powershell 7에서 동일합니다.
답변
안타깝게도 encoding="utf-8"
XML 문서 선언에 속성 이 명시 적으로 존재 하면 대상 파일 경로가 제공되는 경우 BOM.Save()
이있는 UTF-8 인코딩 파일 로 문서에 대한 .NET이 발생하여 실제로 문제가 발생할 수 있습니다.
이 변경 요청 은 이전 버전과의 호환성이 깨질 까봐 거부되었습니다. 여기 에 최소한 동작을 문서화 하라는 요청 이 있습니다.
다소 역설적 부재 의 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 권장 사항은 BOM과 encoding
속성 이 모두없는 경우 UTF-8을 기본값으로 효과적으로 지정 하기 때문에 안전 합니다.
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>