Avatar of Stef Merlijn
Stef MerlijnFlag for Netherlands asked on

XML encoding is not added

Hi,

I'm using following code to create an XML. But the Encoding isn't added to the XML. This did work nicely previously, but now it isn't anymore?
How can I solve this?

  Doc := NewXMLDocument;
  Doc.Version  := '1.0';
  Doc.Encoding := 'utf-8';
  TijdelijkeString := Doc.XML.Text;

Open in new window


The XML should look like:
<?xml version="1.0" encoding="UTF-8"?>
Delphi

Avatar of undefined
Last Comment
Stef Merlijn

8/22/2022 - Mon
MerijnB

I'm not really used to using MSXML (for Dephi I use a third party XML library), but it seems the encoding attribute is only added if you set it to something different then UTF-8. If I change your code to:
  Doc := NewXMLDocument;
  Doc.Version  := '1.0';
  Doc.Encoding := 'utf-16';

Open in new window


the encoding attribute is added, it almost looks like default MSXML behaviour. Why do you need it to be there?

(en de groeten :p)
Sinisa Vuk

Please note - activate xml document first:

var
  Xml: IXmlDocument;
begin
  CoInitialize(nil);
  try
    Xml := NewXMLDocument;
    Xml.Active := True;
    Xml.Options := Xml.Options + [doNodeAutoIndent];
    Xml.ParseOptions := Xml.ParseOptions + [poPreserveWhiteSpace];
    Xml.Encoding := 'UTF-8';
    ShowMessage(Xml.XML.Text);
  finally
    CoUninitialize;
  end;

Open in new window

MerijnB

@sinisav, check the implementation of NewXMLDocument()

function NewXMLDocument(Version: DOMString = '1.0'): IXMLDocument;
begin
  Result := TXMLDocument.Create(nil);
  Result.Active := True;
  if Version <> '' then
    Result.Version := Version;
end;

Open in new window


As you can see, it sets active to true for you :)

When I test your code here, there is still no encoding attribute added.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER
Stef Merlijn

MerlijnB: The XML must be build up in a certain way, as it is described in the SEPA documentation. They apparently require the encoding.
ASKER
Stef Merlijn

Sinisav: Your code gives the same result here:

<?xml version="1.0"?>
in stead of
<?xml version="1.0" encoding="UTF-8"?>
ASKER
Stef Merlijn

It's a strange behaviour. Even when I manually add the encoding it still drops of after I load the string to XML.
    sDoc := Doc.XML.Text;
    sDoc := StringReplace(sDoc, 'encoding="utf-16"', 'encoding="utf-8"', [rfReplaceAll]);
    Doc := LoadXMLData(sDoc);

Open in new window


Found this code in XMLDoc:
function XMLStringToUnicodeString(const XMLString: AnsiString): UnicodeString;
const
  AnsiEncodings: array[0..1] of string = ('ISO-8859-1', 'US-ASCII');
  UnicodeEncodings: array[0..2] of string = ('UTF-16', 'UCS-2', 'UNICODE');
var
  Encoding: string;
begin
  Encoding := ExtractAttrValue(SEncoding, Copy(string(XMLString), 1, 50), '');
  { No Encoding is assumed to be UTF-8 }
  if (Encoding = '') or SameText(Encoding, 'UTF-8') then
    Result := UTF8ToString(XMLString)
  { Latin1 and ASCII can use standard AnsiString->UnicodeString conversion }
  else if EncodingMatches(Encoding, AnsiEncodings) then
    Result := string(XMLString)
  else
  { All others fail }
    XMLDocError(SUnsupportedEncoding, [Encoding]);
  CheckEncoding(Result, UnicodeEncodings);
end;

Open in new window


So I guess it is the default XML-encoding as MerijnB has mentioned.
It is still strange that I was able to add the 'utf-8' encoding before???
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
MerijnB

@DelphiWizard

for some reason this seems to be a workaround:

var xml: IXMLDocument;
    s: utf8string;
begin
 Xml := NewXMLDocument;
 Xml.Options := Xml.Options + [doNodeAutoIndent];
 Xml.ParseOptions := Xml.ParseOptions + [poPreserveWhiteSpace];
 Xml.Encoding := 'UTF-8';
 XML.SaveToXML(s);
end;

Open in new window


Note that s is an utf8string! If you change it to a normal string it stops working.

Alternatively you could check out 3th party libraries (like SimDesign's TNativeXML: http://www.simdesign.nl/xml.html)
ASKER
Stef Merlijn

MerijnB: Which external XML library do you use?
Sinisa Vuk

I guess it depends on delphi version. In newer delphi strings are unicode (and not utf8), so there is no encoding in your app, but I have it (D6). So, this utf8string is good as is ansistring too in your example.
Your help has saved me hundreds of hours of internet surfing.
fblack61
MerijnB

@DelphiWizard, we use TNativeXML
ASKER
Stef Merlijn

MerijnB: Your code produces the same result.
I guess    Doc := LoadXMLData(sDoc);
Removes the utf-8 encoding in the end.
MerijnB

Why do you call LoadXMLData() ?

To get the XML, just do  XML.SaveToXML(s), where s is an UTF8string
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Stef Merlijn

After building the whole XMl, I need to replace a string.
var sDoc : UTF8String;
begin
    sDoc := Doc.XML.Text;
    sDoc := StringReplace(sDoc, '<CstmrDrctDbtInitn xmlns="">', '<CstmrDrctDbtInitn>', [rfReplaceAll]);
    Doc := LoadXMLData(sDoc);
    Doc.SaveToFile(ExportMap + 'SEPA XML ' + FormatDateTime('yyyy-mm-dd',Date) + '.xml');
end;

Open in new window

Where do you assign content to var "s"?
ASKER CERTIFIED SOLUTION
MerijnB

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
See how we're fighting big data
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
ASKER
Stef Merlijn

Looks good, however this is not working.

    // get the XML data in a utf-8 string to force utf-8 attribute
    sTemp := Doc.SaveToXML(sTemp);

Incompatible types: 'UTF8String' and 'procedure, untyped pointer or untyped parameter'
SOLUTION
Log in to continue reading
Log In
Sign up - Free for 7 days
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
ASKER
Stef Merlijn

Perfect, thank you very much.
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
ASKER
Stef Merlijn

To be complete:
Creating the file can be as easy as:
TFile.WriteAllText('c:\somefile.xml', sDoc);  // uses IOUtils

Open in new window