delphi – 防止XSLT转换将utf-8 XML转换为utf-16?
在Delphi XE2中,我正在对收到的
XML文件进行xslt转换,以删除所有命名空间信息.
问题:它改变了 <?xml version="1.0" encoding="utf-8"?> 成 <?xml version="1.0" encoding="utf-16"?> 这是我从Exchange服务器返回的XML: <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:ServerVersionInfo MajorVersion="14" MinorVersion="0" MajorBuildNumber="722" MinorBuildNumber="0" Version="Exchange2010" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/> </s:Header> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <m:ResolveNamesResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:ResolveNamesResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:ResolutionSet TotalItemsInView="1" IncludesLastItemInRange="true"> <t:Resolution> <t:Mailbox> <t:Name>developer</t:Name> <t:EmailAddress>developer@timetellbv.nl</t:EmailAddress> <t:RoutingType>SMTP</t:RoutingType> <t:MailboxType>Mailbox</t:MailboxType> </t:Mailbox> <t:Contact> <t:Culture>nl-NL</t:Culture> <t:DisplayName>developer</t:DisplayName> <t:GivenName>developer</t:GivenName> <t:EmailAddresses> <t:Entry Key="EmailAddress1">SMTP:developer@timetellbv.nl</t:Entry> </t:EmailAddresses> <t:ContactSource>ActiveDirectory</t:ContactSource> </t:Contact> </t:Resolution> </m:ResolutionSet> </m:ResolveNamesResponseMessage> </m:ResponseMessages> </m:ResolveNamesResponse> </s:Body> </s:Envelope> 这是删除命名空间信息的函数: Uses MSXML2_TLB; // IXMLDOMdocument class function TXMLHelper.RemoveNameSpaces(XMLString: String): String; const // An XSLT script for removing the namespaces from any document. // From http://wiki.tei-c.org/index.php/Remove-Namespaces.xsl cRemoveNSTransform = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' + '<xsl:output method="xml" indent="no"/>' + '<xsl:template match="/|comment()|processing-instruction()">' + ' <xsl:copy>' + ' <xsl:apply-templates/>' + ' </xsl:copy>' + '</xsl:template>' + '<xsl:template match="*">' + ' <xsl:element name="{local-name()}">' + ' <xsl:apply-templates select="@*|node()"/>' + ' </xsl:element>' + '</xsl:template>' + '<xsl:template match="@*">' + ' <xsl:attribute name="{local-name()}">' + ' <xsl:value-of select="."/>' + ' </xsl:attribute>' + '</xsl:template>' + '</xsl:stylesheet>'; var Doc,XSL: IXMLDOMdocument2; begin Doc := ComsDOMDocument.Create; Doc.ASync := false; XSL := ComsDOMDocument.Create; XSL.ASync := false; try Doc.loadXML(XMLString); XSL.loadXML(cRemoveNSTransform); Result := Doc.TransFormNode(XSL); except on E:Exception do Result := E.Message; end; end; { RemoveNameSpaces } 但在此之后,它突然变成了一个utf-16文件: <?xml version="1.0" encoding="UTF-16"?> <Envelope> [snip] </Envelope> 谷歌搜索“xsl utf-8 utf-16”后我尝试了几件事: >更改线路(例如Output DataTable XML in UTF8 rather than UTF16) <xsl:output method="xml" indent="no"> 进入: <xsl:output method="xml" encoding="utf-8" indent="no"/> <xsl:output method="xml" encoding="utf-8"/> <xsl:output encoding="utf-8"/> 那没用. <xsl:output method="xml" indent="no"/> 成 <xsl:output method="xml" omit-xml-declaration="yes" indent="no" /> 这会遗漏起始的xml标签,但如果我只是前置 <?xml version="1.0" encoding="utf-8"?> 我将丢失字符,因为没有进行实际的utf转换. 任何想法如何解决这一问题? 备注/背景: >如果所有其他方法都失败了,可能仍然可以选择将utf-16 XML数据更改为utf-8,但这是一种完全不同的方法. 解决方法
要在原始代码中使用IXMLDocument,它应如下所示:
var iInp,iOtp,iXsl: IXMLDocument; Utf8: UTF8String; begin iInp := LoadXMLData(XMLString); iXsl := LoadXMLData(cRemoveNSTransfrom); iOtp := NewXMLDocument; iInp.Node.TransformNode(iXsl.Node,iOtp); iOtp.SaveToXML(Utf8); end 现在变量Utf8应包含UTF-8编码的转换XML,如果要保存为流/文件,请将SaveToXML替换为 iOtp.Encoding := 'UTF-8'; iOtp.SaveToFile(....); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |