2013-04-18 16 views
5

डेल्फी XE2 में, मैं सभी नेमस्पेस जानकारी को निकालने के लिए प्राप्त XML फ़ाइल पर एक xslt रूपांतरण कर रहा हूं।
समस्या: यहयूटीएफ -8 एक्सएमएल को यूटीएफ -16 में परिवर्तित करने से एक्सएसएलटी ट्रांसफॉर्म को रोकें?

<?xml version="1.0" encoding="utf-8"?> 

बदलता है

<?xml version="1.0" encoding="utf-16"?> 

में यह 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>[email protected]</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:[email protected]</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> 

Googling "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"/> 
    

    कि काम नहीं किया।
    (यह, इष्टतम समाधान होगा http://www.xml.com/pub/a/2002/09/04/xslt.html के अनुसार, "एन्कोडिंग विशेषता वास्तव में परिणाम दस्तावेज़ के लिए एक एन्कोडिंग घोषणा जोड़ने की तुलना में अधिक होता है, यह XSLT प्रोसेसर बताता है कि एन्कोडिंग का उपयोग परिणाम को लिखने के लिए।")

  • <xsl:output method="xml" omit-xml-declaration="yes" indent="no" /> 
    

    जो शुरू एक्सएमएल टैग छोड़ देता है, लेकिन अगर मैं तो बस जनसंपर्क में लाइन (जैसे XslCompiledTransform uses UTF-16 encoding)

    <xsl:output method="xml" indent="no"/> 
    

    बदलें एपेंड

    <?xml version="1.0" encoding="utf-8"?> 
    

    मैं अक्षर खो दूंगा क्योंकि कोई वास्तविक यूटीएफ रूपांतरण नहीं किया जाता है।

  • IXMLDOMdocument2 एक Encoding संपत्ति

कोई भी विचार कैसे इसे ठीक करने की जरूरत नहीं है?

टिप्पणियां/पृष्ठभूमि:

  • सब और अगर वहाँ शायद अभी भी utf-8 के लिए UTF-16 XML डेटा बदलने का विकल्प है विफल रहता है, लेकिन यह है कि एक बिल्कुल अलग तरीका है।

  • मैं सब कुछ utf-8 करने की कोशिश कर रहा हूं क्योंकि मैं ईडब्ल्यूएस के माध्यम से एक्सचेंज सर्वर के साथ संचार कर रहा हूं, और http अनुरोध हेडर को utf-16 पर सेट नहीं करता है: एक्सचेंज मुझे बताता है कि सामग्री-प्रकार 'टेक्स्ट/xml; charset = utf-16 'अपेक्षित प्रकार' टेक्स्ट/xml नहीं है; charset = utf-8 '।ईडब्ल्यूएस यूटीएफ -8 लौटाता है (पोस्ट की शुरुआत देखें)।

+2

@Gserg स्वरूपण संपादन के लिए धन्यवाद, मैं बुलेट बिंदुओं में कोड ब्लॉक के साथ कुश्ती कर रहा था। –

उत्तर

1

आप मूल कोड में 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 एन्कोडिंग में तब्दील एक्सएमएल शामिल करना चाहिए, तो आप धारा/फाइल करने के लिए बचाने के लिए चाहते हैं, SaveToXML की जगह

iOtp.Encoding := 'UTF-8'; 
    iOtp.SaveToFile(....); 
2

समस्या transformNode विधि का प्रयोग होता है, यह एक स्ट्रिंग वापस आती है और MSXML के साथ इस तरह के एक स्ट्रिंग UTF-16 एन्कोड किया गया है। इसलिए आपको परिणाम के लिए एक खाली एमएसएक्सएमएल डोम दस्तावेज़ बनाने की आवश्यकता है और the transformNodeToObject method का उपयोग करें, खाली डॉम दस्तावेज़ को दूसरे तर्क के रूप में पास करते हुए, आप परिणाम दस्तावेज़ को फ़ाइल या स्ट्रीम में सहेज सकते हैं और एन्कोडिंग को xsl:output निर्देश में निर्दिष्ट किया जाना चाहिए ।

+0

मैं कहूंगा कि डीओएम को यूटीएफ -16 का उपयोग करके आंतरिक रूप से लागू किया गया है, इसलिए लक्ष्य डीओएम दस्तावेज़ में परिवर्तन का परिणाम यूटीएफ -16 में भी एन्कोड किया जाएगा। प्रति एन्कोडिंग इनपुट/आउटपुट फ़िल्टर के लिए एक कार्य होना चाहिए, इसलिए मुझे उम्मीद है कि यह कॉल करने के लिए आवश्यक है उदा। 'iXMLDocument.SaveToXML (AUTF8String)' – pf1957

+0

एमएसएक्सएमएल में 'SaveToXML' नामक विधि नहीं है। इसमें डीओएम दस्तावेजों पर 'सेव' नामक एक विधि है और मेरा सुझाव है कि उस विधि का उपयोग एक डीओएम दस्तावेज़ पर करें जिसे खाली बनाया गया था और फिर 'transformNodeToObject' विधि में पारित किया गया था। इस तरह, यदि आप किसी फ़ाइल या स्ट्रीम में सहेजते हैं, तो एन्कोडिंग के रूप में होना चाहिए। यदि आप 'transformNode' का उपयोग करते हैं तो यह संभव नहीं है। –

+0

मुझे पता है। मैं सीधे एमएसएक्सएमएल को कॉल नहीं करता था लेकिन 'IXMLDocument' /' IXMLNode' के माध्यम से। अधिभारित विधियां 'ट्रांसफॉर्म नोड' हैं और उनमें से एक 'transformNodeToObject' को कॉल करती है। मेरी टिप्पणी ने उचित एन्कोडिंग सुनिश्चित करने के लिए ** ** ** ** ऑपरेशन करने के लिए कुछ प्रकार की निष्पादन करने में विफलता से संबंधित है। इसे आसानी से सहेजा जा सकता है उदा। SaveToXML को कॉल करके और यूटीएफ 8 स्ट्रिंग के प्रकार के विभिन्न तर्क को पारित करके। – pf1957

संबंधित मुद्दे