Link to home
Start Free TrialLog in
Avatar of Michel Plungjan
Michel PlungjanFlag for Denmark

asked on

URGENT: How to rewrite an xml file before saving it in ASP/MSXML

The part from the replace of & gives an error and I am not sure I am doing it right:

<%@ language=javascript %>
<%
    Response.Expires = -1000;
    // Load the posted XML document
    var doc = Server.CreateObject("Microsoft.XMLDOM");
    doc.load(Request);
    doc.save(Server.MapPath("xxYY.xml"));
    doc.save(Server.MapPath("../../xmldir1/xxYY.xml")); // WORKS UNTIL HERE
// I get an unspecified error somewhere from here on
    contentNodes = doc.documentElement.selectNodes("/VARSFILE/VAR/CONTENT")
    for (i=0;i<contentNodes.length;i++) {
       val = contentNodes[i].text;
       if (val.indexOf('&amp;') !=-1) {
         val=val.replace('&amp;','!!!!!!!&!!!!'); // the !!! are to see it really worked
         contentNodes[i].text=val;
         changed=true;
       }
    }
    doc.save(Server.MapPath("../../xmldir2/zzzzzz_YYxx.xml")); // did the contentNodes change at all?

%>
Avatar of MCummings
MCummings

MY first response is that you are generating some invalid XML by replacing the &amp; entity with your string which includes the '&'. If you want the & without using &amp; enclose your content in CDATA nodes.
That seems reasonable, but the thing is, if the input XML looks like:

<VARSFILE>
    <VAR>
        <CONTENT>Foo &amp; Bar</CONTENT>
        <CONTENT>snafu</CONTENT>
        <CONTENT>tarfu</CONTENT>
    </VAR>
</VARSFILE>

there won't be any entities like &amp; in the parsed document object.

When an XML Document is parsed, XML markup entities (like &amp;) are expanded.  So the value of the first <CONTENT> node is actually: "Foo & Bar" where the "&" is the character for the ampersand.  You will ONLY ever find "&amp;" in the *parsed* document if the original XML looks like:

        <CONTENT>Foo &amp;amp; Bar</CONTENT>

or:

        <CONTENT><![CDATA[Foo &amp; Bar]]></CONTENT>

If you view the xml property of the DOM object, you'll see the "&amp;" but that's because the DOM object is serialized, and all markup characters are encoded into their entity equivalents.  

To see what I mean, copy this and save as test.html:

<html>
<script language = "Javascript">
    var doc = new ActiveXObject("Msxml2.DomDocument");
    doc.preserveWhiteSpace = true;
    sXml = ""
    sXml += "<VARSFILE>\n"
    sXml += "  <VAR>\n"
    sXml += "    <CONTENT>Foo &amp; Bar</CONTENT>\n"
    sXml += "    <CONTENT>snafu</CONTENT>\n"
    sXml += "    <CONTENT>tarfu</CONTENT>\n"
    sXml += "  </VAR>\n"
    sXml += "</VARSFILE>"

    doc.loadXML(sXml);
    contentNodes = doc.documentElement.selectNodes("/VARSFILE/VAR/CONTENT")
    alert("This shows an entity, because the XML is serialized.  \nTherefore the ampersand is encoded as an entity\n\n" + doc.xml)
    for (i=0;i<contentNodes.length;i++) {
       val = contentNodes[i].text;
       if (val.indexOf('&') !=-1)
            alert("This shows the entity has been expanded: \n\n" + val)
       if (val.indexOf('&amp;') !=-1) {
       // This never tests true!  No entities in the parsed XML.
            alert("There's an entity in here");
            val=val.replace('&amp;','!!!!!!!&!!!!'); // the !!! are to see it really worked
            contentNodes[i].text=val;
            changed=true;
       }
       contentNodes[i].text = val + "&"
       alert("The new Content node (contentNodes[i].text) isn't parsed, so \nit doesn't matter that I add an ampersand!\n\n" + contentNodes[i].text)

    }
    alert("Here's the modified XML.  All ampersands have been encoded: \n\n" + doc.xml)
</script>
</html>

As far as the error you get....I don't see a problem  The code I pasted here is fine.

However, DON'T use the progID "Microsoft.XMLDOM", expecially on the server!.  This is MSXML 2.0.  You should use at least MSXML 3.  So don't do this:

    var doc = Server.CreateObject("Microsoft.XMLDOM");

but do this:

    var doc = Server.CreateObject("Msxml2.DomDocument");


Regards,
Mike Sharp

http://dev.rdcpro.com
I should like to add that if the server has MSXML 3, sp1 or later installed, then even if you *do* use

    var doc = Server.CreateObject("Microsoft.XMLDOM");

it will actually be using MSXML 3 as though you typed:

    var doc = Server.CreateObject("Msxml2.DomDocument");

MSXML 3, sp1 or later installs in replace mode.  That doesn't mean you can leave the "Microsoft.XMLDOM" in there, because it's possible on some servers if there is legacy code, the MSXML 3 might be forcibly installed in side-by-side mode, and your code could have errors if it's referencing the wrong parser.

Regards,
Mike Sharp
Oh, and one more thing...though this should be obvious, using the save() method of the DOM object will escape the entity back into an ampersand, even if your original code had succeeded in finding an entity and replacing it with the "&".  It must do this, because otherwise your saved XML is not well formed.  You would have to use the CDATA section, as MCummings suggested, if you want to retain the "&".  But this is almost never necessary, IMHO.  If you think you need to do it, you've probably got something wrong elsewhere.

Regards,
Mike Sharp
Avatar of Michel Plungjan

ASKER

Thanks for looking, The data looks like this, sorry for not explaining that:

<VARSFILE>
  <VAR>
    <NAME>Name 1</NAME>
    <CONTENT>Foo&amp;lt;br/&amp;gt;Bar</CONTENT>
    <COMMENT>Foo bar split by a br</CONTENT>
  </VAR>
  <VAR>
    <NAME>Name 2</NAME>
    <CONTENT>&amp;lt;span&amp;gt;Snafu&amp;lt;/span&amp;gt;</CONTENT>
    <COMMENT>Snafu in a span</CONTENT>
  </VAR>
</VARSFILE>

and I need to save it as

<VARSFILE>
  <VAR>
    <NAME>Name 1</NAME>
    <CONTENT>Foo&lt;br/&gt;Bar</CONTENT>
    <COMMENT>Foo bar split by a br</CONTENT>
  </VAR>
  <VAR>
    <NAME>Name 2</NAME>
    <CONTENT>&lt;span&gt;Snafu&lt;/span&gt;</CONTENT>
    <COMMENT>Snafu in a span</CONTENT>
  </VAR>
</VARSFILE>


The version of the MSXml seems to be ok. At least the first part works.
I will need to try what you suggested tomorrow
PS and of course the <COMMENT>...</CONTENT> is <COMMENT...</COMMENT>

typo
You should still change the progID to reflect the actual parser being used, which should be MSXML 3 or 4.  Yes, the old progID works, but it might not work in all cases!

Do you want to process a bunch of XML documents that erroneously have double-escaped markup characters, or do you want to do this on a regular basis, as part of normal processing?

In the second case, I'd fix whatever's doing the double-escaping.  I've run into this situation with Interwoven Teamsite, which stored the XML double-escaped.  It essentially parses the XML twice.  

If the first case is the situation, you could always do the string replace for &lt; and &gt; replacing them with < and >.

If you want to use the SAX API, you can set the disableOutputEscaping property of an object implementing IXMWriter interface.  This will suppress the output escaping of the &.  However this should be used with caution, as this normally results in non-well-formed XML documents.  So if there are content nodes that are correctly formed (not double-escaped) then it will generate a bad output.

Or if you want to use XSLT, you can do an identity transformation, and in the appropriate place, use:

<xsl:value-of select="CONTENT" disable-output-escaping="true"/>

The same caution regarding non-well-formed output applies here.

Regards,
Mike Sharp

http://dev.rdcpro.com
Ok, I think this will do what you want:

<html>
<script language = "Javascript">
    var doc = new ActiveXObject("Msxml2.DomDocument");
    doc.preserveWhiteSpace = true;
    sXml = ""
    sXml += "<VARSFILE>\n"
    sXml += "  <VAR>\n"
    sXml += "    <CONTENT>Foo&amp;lt;br/&amp;gt;Bar</CONTENT>\n"
    sXml += "    <CONTENT>snafu</CONTENT>\n"
    sXml += "    <CONTENT>tarfu</CONTENT>\n"
    sXml += "  </VAR>\n"
    sXml += "      <VAR>\n"
    sXml += "    <NAME>Name 2</NAME>\n"
    sXml += "    <CONTENT>&amp;lt;span&amp;gt;Snafu&amp;lt;/span&amp;gt;</CONTENT>\n"
    sXml += "    <COMMENT>Snafu in a span</COMMENT>\n"
    sXml += "  </VAR>\n"
    sXml += "</VARSFILE>"

    doc.loadXML(sXml);
    svar = doc.xml;
    re = new RegExp("&amp;","ig");
    svar = svar.replace(re,"&");
alert(svar);
    doc.loadXML(svar);
    alert(doc.xml);
</script>
</html>
Mike: We are doing double escaping for the xml files we save in the first save since we need that for a later transform that converts the amp
Then on another server we use SAX and THAT needs the &lt; e.g. the file WITHOUT double escaping.

MCummings, would you please add your suggestion to the script I pasted in the original question so it can SAVE the changed file
It seems you are chaning the complete xml as one string - if that works that would be cool.

Michel
chaning=changing

I am off to bed, thanks so far.
I will add points when I have a working version so all will get a share...

Michel
SOLUTION
Avatar of MCummings
MCummings

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Be very careful of converting your XML to a string, doing the regex and then re-parsing it.  This forces encoding to UTF-16, which you may not want, and which can cause you great pain if there are character entity references in there, such as &#160; and so on.  I would do the XSLT identity transform, myself, so as to preserve the original encoding.

<%@ language=javascript %>
<%
    Response.Expires = -1000;
    // Load the posted XML document
    var doc = Server.CreateObject("Msxml2.DomDocument");
    doc.load(Request);
    doc.save(Server.MapPath("xxYY.xml"));
    doc.save(Server.MapPath("../../xmldir1/xxYY.xml")); // WORKS UNTIL HERE
    var xsl = Server.CreateObject("Msxml2.DomDocument");
    xsl.load(Server.MapPath("entity.xsl"))
    var result = Server.CreateObject("Msxml2.DomDocument");
    doc.transformNodeToObject(xsl, result)
    result.save(Server.MapPath("../../xmldir2/zzzzzz_YYxx.xml")); // did the contentNodes change at all?

%>

Using this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                                          xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/ | node()">
      <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()"/>
      </xsl:copy>
</xsl:template>

<xsl:template match="@*">
      <xsl:copy>
      </xsl:copy>
</xsl:template>

<xsl:template match="CONTENT">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:value-of select="." disable-output-escaping="yes"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>


Regards,
Mike Sharp
Thanks a LOT. Yes I am 100% NOT interested in any conversion.
I am not sure I understand what you are doing here. Selecting anything and just doing nothing to let the &amp; resolve itself?
We have encodings of ISO-8859-2, 2 and windows-12XX - are you sure I want the xsl to be UTF8???

Thanks again

Michel
Well, it would resolve itself except in your peculiar circumstance you want it &amp;lt; in one place and &lt; in another...what makes this identity tranform work for you is:

        <xsl:value-of select="." disable-output-escaping="yes"/>

The disable-output-escaping="yes" prevents the processor from escaping a markup character to the output as it otherwise would.  The documentation always cautions you about the potential for mal-formed output doing this...Be aware, though, if you should have the case where the document was actually: &lt; it will disable the output escaping for the "<" as well!

In any case, the transformation takes this:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="entity.xsl"?>
<VARSFILE>
    <VAR>
        <CONTENT>Foo &amp;lt;br /&amp;gt; Bar</CONTENT>
        <CONTENT>snafu</CONTENT>
        <CONTENT>tarfu</CONTENT>
    </VAR>
</VARSFILE>


and turns it into this:

<?xml version="1.0" encoding="UTF-16"?>
<?xml-stylesheet type="text/xsl" href="entity.xsl"?>
<VARSFILE>
<VAR>
<CONTENT>Foo &lt;br /&gt; Bar</CONTENT>
<CONTENT>snafu</CONTENT>
<CONTENT>tarfu</CONTENT>
</VAR>
</VARSFILE>

Note my use of transformNodeToObject in my code sample...this ensures encoding is not forced to UTF-16.  The output of the transform must also be a well-formed XML document, so you can check the parseError property to see if the transformation resulted in a non-well-formed document, which is always a good idea when you're creating an XML document when disable-output-escaping="yes".

Regards,
Mike Sharp
What the XSL is encoded in doesn't really matter.  If you're encoding it in UTF-8 or Windows-1252, or whatever, just set the encoding for xml declaration.  In many cases you can leave it out, as the parser will determine the actual encoding of the XSL document from the BOM.  The output encoding is what you're interested in, and it is set with xsl:output

If you want ISO-8859-2, just put that in your xsl:output like:

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="iso-8859-2" indent="yes"/>

Now, if you play around with this in something like XML Spy, you'll notice all sorts of encoding problems, if you use character entities.  This is because XML Spy seems to use the transformNode() method of the DOM object, which coerces the encoding to UTF-16 as I mentioned before.  But using transformNodeToObject() utilizes the IStream interface, doesn't involve strings at all (BStr is UTF-16), and should preserve your encoding.

Regards,
Mike Sharp

Thanks, great to have someone who is REALLY into these things
I am trying
Ok, it works like a charm
HOWEVER
the statement
    var xsl = Server.CreateObject("Msxml2.DomDocument");
    xsl.load(Server.MapPath("escape.xsl"))
produces the warning
"This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?"

Can I dump the xsl into the asp perhaps in an island?

Thanks

Michel
PS: I upped the points
Is this running on the server?  How do you get the warning?  I've never seen this situation on server-side code--this is a standard IE security warning for cross-domain data access.  As long as the file escape.xsl is in the same domain as the HTML page loading it, you shouldn't see this error even if the code is on the client.  

Describe your architecture a bit to me.  I assumed you had an ASP script that ran and did all the copying, then theoretically did something with the resulting XML?   Is this actually running as a javascript in the filesystem context, or in an HTML page served from your web server?

Regards,
Mike Sharp
I have an HTA running on a client, downloaded from a webserver (iis)

It loads an XML file with CONTENT having in some cases doubly encoded html that we use to create our interfaces with

It transforms the xml to a form using xsl and the user fills in translations of our web interface in their language

When the client is ready, they click save and the hta does a save via http to the asp you have seen here.

The files are used in an ant procedure using xsl to create a website in the language

We ALSO have a server on a java platform that uses sax to read the xml directly (and here it should NOT be doubly encoded)
and those are the files I need to convert.

Thanks

Michel
At which point do you get the cross domain security warning?

Regards,
Mike Sharp
Most likely here
  var xsl = Server.CreateObject("Msxml2.DomDocument");
  xsl.load(Server.MapPath("entity.xsl"))
No, I meant:  at which point in this list:

I have an HTA running on a client, downloaded from a webserver (iis)

It loads an XML file with CONTENT having in some cases doubly encoded html that we use to create our interfaces with

It transforms the xml to a form using xsl and the user fills in translations of our web interface in their language

When the client is ready, they click save and the hta does a save via http to the asp you have seen here.

The files are used in an ant procedure using xsl to create a website in the language

We ALSO have a server on a java platform that uses sax to read the xml directly (and here it should NOT be doubly encoded)
and those are the files I need to convert.



Regards,
Mike Sharp
When the client is ready, they click save and the hta does a save via http to the *ASP* you have seen here.

It is while they save after we added the second save that they get the message.

Michel
Can someone plase show me how to have the xsl inline in the asp?

Thanks
I'm not sure what you mean by inline in the ASP.  If you are talking about inline in the client, you can do it with a data island, like:

<XML id="xsl" >
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-16" indent="yes"/>

<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>

</XML>

and you get access to it using the XMLDocument property:

var newXSL = new ActiveXObject("Msxml2.DomDocument")
newXSL.loadXML(xsl.XMLDocument.xml)

If you mean actually inline in the ASP page, to be executed on the server, it's not necessary.  

I still don't understand exactly where your error message comes from.  If the message is happening on the save, why do you think it's the XSL?  If you have an HTA, loaded from http://foo.com, and you try to save to http://bar.com, you're going to get this message, unless the HTA is downloaded to the local filesystem, and launched from there.  The way you handle this is to funnel everything through a single server, no matter how many actual servers are involved.  It's a hub and spoke model.  So you have the server that talks to the client do all the aggregation and communication with the other servers.  A request for an XSL, even if it exists on http://bar.com, must be fulfilled by http://foo.com, as long as that's the server serving the client.  So http://foo.com loads the XSL using the SetProperty "ServerXMLHTTPRequest" and then "saves" it to the client like:

Client page, loaded from http://foo.com:

xsl = new ActiveXObject("Msxml2.DomDocument")
xsl.load("getRemoteXSL.asp")

This requests an XSL from the same server that sent the page that this code is executing, and so getRemoteXSL.asp on http://foo.com is:

Response.ContentType = "text/xml"
var remoteXSL = new ActiveXObject("Msxml2.DomDocument");
remoteXSL.setProperty("ServerXMLHTTPRequest", true);
remoteXSL.load("http://bar.com/actualXSL.xslt")
remoteXSL.save(Response)

Regards,
Mike Sharp
1. I have an asp page - it saves a file
2. I change it so it loads an xsl to transform the xml before saving

As soon as I added the loading of the xsl in the ASP, the cleint was warned that something not in it's control was being loaded.

I am asking if the ASP can have the statements
   var xsl = Server.CreateObject("Msxml2.DomDocument");
    xsl.load(Server.MapPath("escape.xsl"))

replaced by


var newXSL = new ActiveXObject("Msxml2.DomDocument")
newXSL.loadXML(xsl.XMLDocument.xml)

<XML id="xsl" >
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-16" indent="yes"/>

<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>

</XML>
It may help to see the HTA code that does the saving. This message is from the client, what you are doing in ASP on the server should not be effecting the client. Also are the server that the HTA is loaded from and the Server that the XML file is sent to the same?
1. the save has not changed
2. the hta and asp is from same directory on same server
3. the message goes away when I remove the xsl loading
You can't have a data island on the server, so this won't work:

newXSL.loadXML(xsl.XMLDocument.xml)

_if it's executing on the server_.  But I really can't see how code executing on the server can possibly tell the client that a cross domain data access issue is occuring.  

In other words, if this is the ASP code you're having problems with (including the <% and %>):

<%@ language=javascript %>
<%
    Response.Expires = -1000;
    // Load the posted XML document
    var doc = Server.CreateObject("Msxml2.DomDocument");
    doc.load(Request);
    doc.save(Server.MapPath("xxYY.xml"));
    doc.save(Server.MapPath("../../xmldir1/xxYY.xml")); // WORKS UNTIL HERE
    var xsl = Server.CreateObject("Msxml2.DomDocument");
    xsl.load(Server.MapPath("escape.xsl"))
    var result = Server.CreateObject("Msxml2.DomDocument");
    doc.transformNodeToObject(xsl, result)
    result.save(Server.MapPath("../../xmldir2/zzzzzz_YYxx.xml")); // did the contentNodes change at all?

%>

then I don't see how you can have a cross-domain data access issue.  But if this code is executing on the client, all the Server.Mappath stuff is not right either.  So the only thing I can think of is that after the stylesheet loads, and the transformation occurs, something is sent to the client where there's a link or URL or something that points to a different server.  If this is the case, loading the XSLT differently won't help.   Cross-domain data access is a security issue for the client, not the server.  So if you're getting the error, it must be something that's happening on the client, not the server, either before or after the transformation.

If you can't seem to load the XSLT, is the XSLT on the same server??  If it's on another server, all you have to do is tell the XML DOM object to use the ServerXMLHTTPRequest property, like:

<%@language=JScript%>
<%
var xsl;
xsl= Server.CreateObject("Msxml2.DomDocument");
xsl.async = false;
xsl.setProperty("ServerHTTPRequest", true);  // This tells the DOM object to use HTTP to load the file
xsl.load("http://myRemoteServer.com/xslt/escape.xsl");
%>

If none of this seems to help, you may have to post the entire code, so I can see what's happening and where.  If you don't want to post it, you can zip and email it to me at rdcpro@hotmail.com.  If the attachment is large, let me know and I'll set up a place on my web server where you can upload it.

Regards,
Mike Sharp
I'll set up a test case tomorrow you can have a look at.
Seriously the hta is on the client, saving to the server.
The new code on the server triggers the message on the client and waits for ok

Michel
1) What statements do you remove to make the message go away?
2) What does the ASP script return to the client (if anything?)
the statement
    var xsl = Server.CreateObject("Msxml2.DomDocument");
    xsl.load(Server.MapPath("escape.xsl"))
produces the warning
"This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?"


the script returns a success or not

   rewriteXML();
   var oXml = new ActiveXObject("Microsoft.XMLDOM");
   oXml.load(newXmlID.XMLDocument);
   var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
   xmlhttp.Open("POST", "http://xxxx/whatever.asp", false);
   xmlhttp.Send(oXml);
   if (xmlhttp.responseText!='') alert('Error occurred sending the data:\n'+xmlhttp.responseText);

Michel
the test case would be great...This is a really weird problem, because if the HTA is actually loaded from the local client filesystem, it doesn't matter WHERE the code tries to load the XSL file.  Even if it's an HTML page, not an HTA, and it's sitting on the client filesystem, you can still load pages from multiple sources without the error.  My transformationTool is an example of this.  

http://dev.rdcpro.com/Members/rdcpro/tools/

You can enter the URL of, say, Google, and get the response back, placing it into the web page.  This would generate the error you're talking about if the HTML page was served from a web server, not the local client.  But if the page is served from the client filesystem, it shouldn't generate a cross-domain error at all, because the security context of the filesystem is higher than the site you're trying to access.  So if you go to that URL above, and click "Load HTML" to see an error message.  Then download and unpack the zip file to a local drive, and open the HTML page.  Now click "Load HTML" and it should work fine, even if you've disabled cross-domain data access.

Regards,
Mike Sharp

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I am not getting an error, only a warning..

However I will make sure the server IS the same. I am pretty sure it is, but I will double check tomorrow.
The domain is the same, but we are juggling some 30 countries...
Michel, did you try my suggestion?
He previously said he was using a number of different encodings in the XML, none of which were UTF-16.   Serializing to a string, using the xml property as in contentNodes[0].xml, will force the encoding to be UTF-16 (a BStr is essentially Unicode UTF-16).  Then, when the FSO does the save, the resulting encoding will not be the desired one.  

Regards,
Mike Sharp
hi Mike,

before to send, i tried and for me, with FSO saving, works fine.
so my suggestion is working example.
on test i used:

==============test.asp===================
<%@ language=javascript %>
      <%
      Response.Expires = -1000
      // Load the posted XML document
      var doc = Server.CreateObject("Microsoft.XMLDOM");
      //if(doc.load(Request))
      if(doc.load(Server.MapPath("xxYY.xml")))
      {
            contentNodes = doc.documentElement.selectNodes("//");
            replaceAndsave(contentNodes[0].xml,"zzzzzz_YYxx.xml");
      }
   
function replaceAndsave(doc,filename)
{
      //var doc = edxid.getXmlNode().xml;
      doc = doc.replace(/&amp;gt;/g,"&gt;");
      doc = doc.replace(/&amp;lt;/g,"&lt;");
      
      try
      {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var ts = fso.CreateTextFile(Server.MapPath(filename), true );
            ts.Write(doc);
            ts.Close();
            Response.Write( "Saved document: " + filename);
      }
      catch(e)
      {
            Response.Write( "Error - document not saved.");
      }
}

%>

====================xxYY.xml===================
<VARSFILE>
 <VAR>
   <NAME>Name 1</NAME>
   <CONTENT>Foo&amp;lt;br/&amp;gt;Bar</CONTENT>
   <COMMENT>Foo bar split by a br</COMMENT>
 </VAR>
 <VAR>
   <NAME>Name 2</NAME>
   <CONTENT>&amp;lt;span&amp;gt;Snafu&amp;lt;/span&amp;gt;</CONTENT>
   <COMMENT>Snafu in a span</COMMENT>
 </VAR>
</VARSFILE>


as result is new file "zzzzzz_YYxx.xml", where "&amp;lt;" is "&lt;" and "&amp;gt;" is "&lt;"

i thought Michel wanted this.
Yes, but those chars are not living in a vacuum. They are surrounded by text from 35 countries and switching codepage will mess them up badly ;)

Thanks

I checked. The files are from the same server they are saved to.

Michel
My point was that as soon as you serialize the XML, you end up with UTF-16, and the original encoding is lost.  Then the FSO saves the file in the wrong encoding.  That's the problem with the RegEx approach--it doesn't take into account encoding.  Michel previously stated he did not want to change the encoding.  If you saved a stream, then you could preserve the encoding, but you've already changed it when you did the RegEx.  



Regards,
Mike Sharp