XML String-encoding

english preferred?


Im XML-String dürfen die Ampersand „&“ und die spitzen Klammern, kleiner als „<“ und größer als „>“, nicht vorkommen. Denn XML ist Text und benutzt die spitzen Klammern um Tags einzurahmen und den Ampersand um codierte Zeichen zu starten. Aus & wird &amp; aus < wird &lt; und aus > wird &gt;. Die Lösung für ewige 4Dler:
$returnText:=Replace string($givenText;“&“;“&amp;“)
$returnText:=Replace string($returnText;“<„;“&lt;“)
$returnText:=Replace string($returnText;“>“;“&gt;“)
hat einen Haken. Ist der Text bereits codiert, wird aus  &amp; ein doppelt-codiertes &amp;amp; … der Empfänger, z.B. der Xerces-Parser oder SQLite, flippt aus.

Also erst prüfen, ob bereits codiert und nur wenn nicht, selber codieren
Case of
: (Position(„&amp;“;$givenText)>0)
: (Position(„&lt;“;$givenText)>0)
: (Position(„&gt;“;$givenText)>0)
Else
$returnText:=Replace string($givenText;“&“;“&amp;“)
$returnText:=Replace string($returnText;“<„;“&lt;“)
$returnText:=Replace string($returnText;“>“;“&gt;“)
End case

Das Codieren nimmt mir 4D ab. Dazu reicht es mit den XML-Befehlen einem Element einen String zuzuweisen, wie hier:
$xmlKnoten:=“string-to-encode“
$root_t:=DOM Create XML Ref($xmlKnoten)
DOM SET XML ELEMENT VALUE($root_t;$xmlKnoten;$givenText)
DOM EXPORT TO VAR($root_t;$returnText)
DOM CLOSE XML($root_t)
Wird dieser Text
Ein Ampersand & und Spitze Klammen <, > in diesem Text
übergeben steht in $returnText dann das codierte XML-Element
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<string-to-encode>Ein Ampersand &amp; und Spitze Klammen &lt;, &gt; in diesem Text</string-to-encode>

Ich muß mir also den Text zwischen <string-to-encode> und </string-to-encode> rausholen.

Das klappt nicht über
DOM GET XML ELEMENT VALUE ( $root_t;$returnText)
Dann habe ich in $returnText wieder
Ein Ampersand & und Spitze Klammen <, > in diesem Text
stehen.

Vorher die Option zum String encoding auf „Finger weg“ stellen hilft nicht.
XML SET OPTIONS($root_t;XML String encoding;XML raw data)
wird trotzdem decodiert.

Im Handbuch (deutsch und englisch) steht es drin, man muß es nur verstehen

gibt an, wie 4D Strings in Elementwerte konvertiert werden

XML SET OPTIONS wirkt nur auf 4D String in Elementwert einsetzen. Nicht umgekehrt, Elementwert nach 4D String. Schade!


lieber auf deutsch?

XML-Strings can’t contain ampersands „&“ nor angle brackets, smaller than „<“ and greater than „>“.
This is because XML is text and needs the angle brackets to enclose tags and the ampersand to mark the start of an encoded character. & encodes to &amp; and < ist equal to &lt; as > equals &gt;. 4D-veterans will write:
$returnText:=Replace string($givenText;“&“;“&amp;“)
$returnText:=Replace string($returnText;“<„;“&lt;“)
$returnText:=Replace string($returnText;“>“;“&gt;“)
which has a catch. If the text is already encoded, &amp; will get encoded again to &amp;amp; … and the recipient, e.g. Xerces-parser or sqlite, will run amok.

We need to check first if already encoded and only do our encoding if not encoded
Case of
: (Position(„&amp;“;$givenText)>0)
: (Position(„&lt;“;$givenText)>0)
: (Position(„&gt;“;$givenText)>0)
Else
$returnText:=Replace string($givenText;“&“;“&amp;“)
$returnText:=Replace string($returnText;“<„;“&lt;“)
$returnText:=Replace string($returnText;“>“;“&gt;“)
End case

Could be easier. 4D already knows how to encode. This couple of lines will do:
$xmlKnoten:=“string-to-encode“
$root_t:=DOM Create XML Ref($xmlKnoten)
DOM SET XML ELEMENT VALUE($root_t;$xmlKnoten;$givenText)
DOM EXPORT TO VAR($root_t;$returnText)
DOM CLOSE XML($root_t)
Starting with this text
Ein Ampersand & und Spitze Klammen <, > in diesem Text
I’ll receive in $returnText the coded XML-element
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<string-to-encode>Ein Ampersand &amp; und Spitze Klammen &lt;, &gt; in diesem Text</string-to-encode>

All I have to do is get the text between <string-to-encode> and </string-to-encode>.

DOM GET XML ELEMENT VALUE ( $root_t;$returnText)
does not help. The received text in $returnText is again
Ein Ampersand & und Spitze Klammen <, > in diesem Text.

Setting the XML-option „don’t touch“ is of no help.
XML SET OPTIONS($root_t;XML String encoding;XML raw data)
4D decodes anyway.

The manual (english, same in german) explains correctly, but I have to understand

Specifies the way 4D strings are converted to element values

XML SET OPTIONS influences the way a 4D string is converted to an element-value. It’s of no use the other way around, convert an element-value to a 4D string. Pity!