当前位置: 首页 > 知识库问答 >
问题:

Powershell XML文档保存为UTF-8没有BOM

解宏扬
2023-03-14

构建了一个System类型的XML对象。Xml。XmlDocument。

$scheme.gettype()
IsPublic IsSerial Name BaseType                                                         
-------- -------- ---- --------                                                         
True     False    XmlDocument System.Xml.XmlNode 

我使用保存()方法将其保存到文件中。

$scheme.save()

这会将文件以UTF-8格式与BOM一起保存。BOM表会导致后续的其他脚本出现问题。

当我们在记事本中打开XML文件并将其保存为UTF-8(没有BOM)时,其他脚本不会有问题。所以我被要求保存没有BOM的脚本。

保存方法的MS文档说明:

encoding属性的值取自XmlDeclaration。编码属性。如果XmlDocument没有XmlDeclaration,或者XmlDeclaration没有编码属性,则保存的文档也不会有编码属性。

XmlDeclaration上的MS文档列出了UTF-8、UTF-16等的编码属性。它没有提到BOM表。

XmlDeclaration是否具有省略BOM的编码属性?

另外,此行为在Powershell 5和Powershell 7中是相同的。

共有2个答案

越昊穹
2023-03-14

正如BACON在注释中解释的那样,XML声明中Encoding属性的字符串值与包含文档的文件的编码方式没有任何关系。

您可以通过创建带有非BOM的UTF8EncodingStreamWriterXmlWriter来控制这一点,然后将其传递到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>
罗凯
2023-03-14

不幸的是,在XML文档的声明中显式存在编码="utf-8"属性会导致。NET到。如果给定目标文件路径,则将文档保存()到具有BOM的UTF-8编码文件中,这确实会导致问题。

更改此项的请求被拒绝,因为担心破坏向后兼容性;这里有一个至少记录行为的请求。

有点讽刺的是,缺少编码属性会导致。保存()以创建没有BOM的UTF-8编码文件。

因此,一个简单的解决方案是删除编码属性[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和编码属性的情况下有效地强制将UTF-8作为默认值

 类似资料:
  • 我正在尝试将一些UTF-8字符输出到JSON文件。 当我保存文件时,它们是像这样编写的: {“some_key”: “Enviar invitaci\u00f3n privada”} 上述操作是有效的。当我加载文件并打印“some_key”时,它会在终端中显示“Enviar invitación Private ada”。 是否无论如何都要编写带有“some_key”作为编码版本的JSON文件,如

  • 问题内容: 我在Java中有以下代码行: 编写者不会编写UTF-8文件,因为当我在notepad ++中打开文件时,它表示编码为:ANSI作为UTF-8。我需要它是纯UTF-8。 你有什么建议吗? 问题答案: notepad ++(和任何其他工具)只能 猜测 编码,它不会写在文件(或某些元数据)的任何位置。 并且,如果您编写的文本不包含ASCII范围之外的任何字符(即,Unicode码点> 127

  • 我尝试用JasperReport导出CSV文件,问题是当我想打印像“€”这样的货币时。 当我搜索解决方案时,我意识到这是关于文件编码的!我写这个代码! JasperReport导出的文件编码在“没有BOM的UTF-8”上。所以当我用Excel打开文件时,“€”看起来像“,”。但是当我用记事本打开文件时,“€”看起来像“€”。 在记事本上,我将文件编码转换为UTF-8(我认为是BOM),我保存文件。

  • 问题内容: 这里有两个问题。我有一组通常是带有BOM的UTF-8文件。我想将它们(理想情况下)转换为没有BOM的UTF-8。似乎可以解决这个问题。但是我真的看不到任何有关用法的好例子。这将是处理此问题的最佳方法吗? 同样,如果我们能够处理清楚知道的不同输入编码(看到的ASCII和UTF-16),那将是理想的。看来这一切都是可行的。是否有一种解决方案可以采用任何已知的Python编码并以UTF-8格

  • 问题内容: 我有一个带有特殊重音的CSV文件,并通过选择UTF-8编码将其保存在记事本中。当我使用Java读取文件时,它也会读取BOM表字符。 因此,我想以UTF-8格式保存此文件,而不必最初在记事本中附加BOM。 否则,Java中是否有内置类可以消除读取文件内容时开头出现的BOM字符? 问题答案: 使用Notepad -免费且比Notepad好得多。使用Enconding > 在没有BOM的UT

  • 示例代码(在REPL中): 输出: 问题是:它不是人类可读的。我的(聪明的)用户希望用JSON转储来验证甚至编辑文本文件(我宁愿不使用XML)。 有没有办法将对象序列化为UTF-8 JSON字符串(而不是)?