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,而不是在隐式转换为只有Invoke-WebRequest $rssUrl的字符串时进行回复。

相关内容

  • 没有找到相关文章

最新更新