>#define NL (CHR(13)+CHR(10)) > >m.lcInput = [<?xml version="1.0" encoding="iso-8859-1" ?>] + NL +; > [<my-songs>] + NL +; > [<song>] + NL +; > [<song-title song.lang="fr">La valse à mille temps</song-title>] + NL +; > [<singer nat="be">Jacques Brel</singer>] + NL +; > [</song>] + NL +; > [<song>] + NL +; > [<song-title song.lang="en">If walls could talk</song-title>] + NL +; > [<singer nat="ca">Céline Dion</singer>] + NL +; > [</song>] + NL +; > [</my-songs>] + NL > >LOCAL xpto as MSXML2.DOMDocument30, xyz as MSXML2.DOMDocument30 > >m.xpto = CREATEOBJECT("MSXML2.DOMDocument.3.0") >m.xpto.async = .F. >m.xpto.loadXML(m.lcInput) >m.xyz = CREATEOBJECT("MSXML2.DOMDocument.3.0") >m.xyz.async = .F. > >m.xyz.loadXML(ReEncodeXML("iso-8859-1",m.xpto)) > >clear >? m.xyz.xml > >* >* ReEncodeXML >* >* Rebuild a XML document assuring a specific character encoding >* >* Parameters: >* tcTargetEncoding - such as "utf-8" or "iso-8859-1" >* tvDocument - XML document in string or object form >* Returns: >* a XML string under the specified encoding >FUNCTION ReEncodeXML (tcTargetEncoding AS String, tvDocument AS Object) > LOCAL lcReencoder AS String > LOCAL loXML AS MSXML2.DOMDocument30 > LOCAL loStyleSheet AS MSXML2.DOMDocument30 > LOCAL loResult AS MSXML2.DOMDocument30 > LOCAL lcResultFile AS String > LOCAL lcResultXML AS String > > * compose the reencoder stylesheet > * it's just a simple stylesheet to copy the entire document under the specified encoding > * - ok, that was the original comment: now, what this particular stylesheet does is to > * traverse all XML tree, looking for attribute and elements with names with . and - in > * them and change them to _ so that XMLTOCURSOR can read them properly > m.lcReencoder = [<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">] + NL +; > [<xsl:output method="xml" ] +; > [encoding="] + LOWER(ALLTRIM(m.tcTargetEncoding)) + [" ] +; > [omit-xml-declaration="no" indent="yes"/> ] + NL +; > [<xsl:template match="@*">] + NL +; > [<xsl:choose>] + NL +; > [<xsl:when test="contains(name(),'-') or contains(name(),'.')">] + NL +; > [<xsl:attribute name="{translate(name(),'-.','__')}">] + NL +; > [<xsl:value-of select="." />] + NL +; > [</xsl:attribute>] + NL +; > [</xsl:when>] + NL +; > [<xsl:otherwise>] + NL +; > [<xsl:copy />] + NL +; > [</xsl:otherwise>] + NL +; > [</xsl:choose>] + NL +; > [</xsl:template>] + NL +; > [<xsl:template match="/ | node()">] + NL +; > [<xsl:choose>] + NL +; > [<xsl:when test="contains(name(),'-') or contains(name(),'.')">] + NL +; > [<xsl:element name="{translate(name(),'-.','__')}">] + NL +; > [<xsl:apply-templates select="@* | node()"/>] + NL +; > [</xsl:element>] + NL +; > [</xsl:when>] + NL +; > [<xsl:otherwise>] + NL +; > [<xsl:copy>] + NL +; > [<xsl:apply-templates select="@* | node()"/>] + NL +; > [</xsl:copy>] + NL +; > [</xsl:otherwise>] + NL +; > [</xsl:choose>] + NL +; > [</xsl:template>] + NL +; > [</xsl:stylesheet>] + NL > > * create an XML object from the string or uses the supplied one as parameter > IF TYPE("m.tvDocument")="C" > m.loXML = CREATEOBJECT("MSXML2.DOMDocument.3.0") > m.loXML.async = .F. > m.loXML.loadXML(m.tvDocument) > ELSE > m.loXML = m.tvDocument > ENDIF > > * create an XML object for the stylesheet > m.loStyleSheet = CREATEOBJECT("MSXML2.DOMDocument.3.0") > m.loStyleSheet.async = .F. > m.loStyleSheet.loadXML(m.lcReencoder) > > * create the reencoded object > m.loResultXML = CREATEOBJECT("MSXML2.DOMDocument.3.0") > m.loResultXML.async = .F. > m.loResultXML.validateOnParse = .T. > > * execute the transformation and store the transformation in the new object > m.loXML.transformNodeToObject(m.loStyleSheet,m.loResultXML) > > * save the result to a temporary file and read it back as a string > m.lcResultFile = ADDBS(SYS(2023))+SYS(2015)+".xml" > m.loResultXML.save(m.lcResultFile) > m.lcResultXML = FILETOSTR(m.lcResultFile) > ERASE (m.lcResultFile) > > * return it > RETURN m.lcResultXML > >ENDFUNC >