xml - Powershell xml解析弄乱了编码
问题描述
我有这个非常简单的脚本:
$rssUrl = "https://elpais.com/rss/elpais/portada.xml"
$FeedXml = [xml](Invoke-WebRequest $rssUrl)
此时如果我把$FeedXml.Save()
提要中的所有重音和特殊字符都称为乱码,就好像编码错误一样。
例如:
Un periodista que viaj?? a Mil??n para
should be:
Un periodista que viajó a Milán para
但(Invoke-WebRequest $rssUrl).Content
会产生正确的输出。
我目前已经这样做了:
$FeedXml = New-Object xml
$resolver = New-Object -TypeName System.Xml.XmlUrlResolver
$resolver.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$reader = New-Object -TypeName System.Xml.XmlReaderSettings
$reader.XmlResolver = $resolver
$reader = [System.Xml.XmlReader]::Create($rssUrl, $reader)
$FeedXml.Load($reader)
在这种情况下$FeedXml.Save()
会产生预期的输出。
我完全无法理解为什么第一个代码,它应该是“正确的方式”它不起作用?
解决方案
所以看起来问题在于,当 PowerShell 将结果转换为Invoke-WebRequest $rssUrl
xml 文档时,它用于[System.Text.Encoding]::ASCII
将原始字节流转换为字符串,在您的情况下,根据 http 请求中的标头,这实际上是一个 utf8 字节流。
PS> $rssUrl = "https://elpais.com/rss/elpais/portada.xml"
PS> $response = Invoke-WebRequest $rssUrl
PS> $response.GetType().FullName
Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject
PS> $response.Headers["Content-Type"]
text/xml; charset=utf-8
这是 BasicHtmlWebResponseObject 的来源:https ://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/BasicHtmlWebResponseObject.Common.cs
你可以看到它继承自 WebResponseObject,ToString 方法在这里:https ://github.com/PowerShell/PowerShell/blob/658837323599ab1c7a81fe66fcd43f7420e4402b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common /WebResponseObject.Common.cs#L88
/// <summary>
/// Returns the string representation of this web response.
/// </summary>
/// <returns>The string representation of this web response.</returns>
public sealed override string ToString()
{
char[] stringContent = System.Text.Encoding.ASCII.GetChars(Content);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
for (int counter = 0; counter < stringContent.Length; counter++)
{
if (!IsPrintable(stringContent[counter]))
{
stringContent[counter] = '.';
}
}
return new string(stringContent);
}
另一方面,(Invoke-WebRequest $rssUrl).Content
是一个已被正确解码的字符串,System.Text.Encoding.UTF8
因此它保留了重音字符。
简而言之,使用(Invoke-WebRequest $rssUrl).Content
which 已经是一个字符串可能会更好,而不是使用Invoke-WebRequest $rssUrl
.
推荐阅读
- python - 抽卡获得无值
- c++ - 难以理解 C++ 上的递归
- c++ - micros() Arduino 中的 for 循环
- flutter - Cupertino Date Picker Flutter NoSuchMethod 错误(datePickerHour())在实现中
- c - 使用结构集中硬件抽象层使代码执行速度变慢
- dialogflow-es - Dialogflow 无法处理 @sys.date 的简写形式
- azure-devops - Azure cli:克隆管道
- c++ - 程序没有正确读取字符串
- python - 无法将值转换为 int python
- asp.net - ASP.net Webform 中的 Page_OnLoad 事件中的会话 ID 为空