Solved

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

Posted on 2003-10-23
46
2,696 Views
Last Modified: 2013-11-19
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?

%>
0
Comment
Question by:Michel Plungjan
  • 21
  • 16
  • 5
  • +1
46 Comments
 

Expert Comment

by:MCummings
ID: 9607922
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.
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9608978
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9609016
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9609052
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9609723
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>


0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9609737
The version of the MSXml seems to be ok. At least the first part works.
I will need to try what you suggested tomorrow
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9609743
PS and of course the <COMMENT>...</CONTENT> is <COMMENT...</COMMENT>

typo
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9610046
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
0
 

Expert Comment

by:MCummings
ID: 9610049
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>
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9610151
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9610164
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
0
 

Assisted Solution

by:MCummings
MCummings earned 100 total points
ID: 9610219
<%@ 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
    svar = doc.xml;
    re = new RegExp("&amp;","ig");
    svar = svar.replace(re,"&");
    doc.loadXML(svar);
    doc.save(Server.MapPath("../../xmldir2/zzzzzz_YYxx.xml")); // did the contentNodes change at all?

%>
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9610556
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9612226
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?
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9612446
We have encodings of ISO-8859-2, 2 and windows-12XX - are you sure I want the xsl to be UTF8???

Thanks again

Michel
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9612457
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9612491
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

0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9612639
Thanks, great to have someone who is REALLY into these things
I am trying
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9612773
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9612775
PS: I upped the points
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9615862
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9616055
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9616421
At which point do you get the cross domain security warning?

Regards,
Mike Sharp
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9617276
Most likely here
  var xsl = Server.CreateObject("Msxml2.DomDocument");
  xsl.load(Server.MapPath("entity.xsl"))
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9617363
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9617589
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9626001
Can someone plase show me how to have the xsl inline in the asp?

Thanks
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9628159
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9628599
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>
0
 

Expert Comment

by:MCummings
ID: 9628657
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?
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9628677
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9629255
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9629427
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
0
 

Expert Comment

by:MCummings
ID: 9629495
1) What statements do you remove to make the message go away?
2) What does the ASP script return to the client (if anything?)
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9629654
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9629663
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

0
 
LVL 25

Assisted Solution

by:devic
devic earned 100 total points
ID: 9629693
hi Michel,

try this:
======================================
<%@ language=javascript %>
      <%
      Response.Expires = -1000
      // Load the posted XML document
      var doc = Server.CreateObject("Microsoft.XMLDOM");
      if(doc.load(Request))
      {
            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.");
      }
}
%>
0
 
LVL 26

Accepted Solution

by:
rdcpro earned 300 total points
ID: 9629785
I don't think this has anything to do with it, but your client side code uses the old MSXML version 2 parser.  Also, using data islands on the client means that in order to load using MSXML 3 (or 4), you have to do is with loadXML() because the XMLDocument property is a MSXML version 2 object, unless MSXML 3 is installed in replace mode (which you can't really guarantee).  So to do it reliably on the client, you need to do it like:

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

HOWEVER, this means whatever is in newXmlID has now been converted to either UTF-16 or UTF-8, depending on the value in the XML declaration.  It's almost always more reliable to avoid XML data islands because of this.  You can get it to work fine, but then along comes a client with MSXML in side-by-side mode (as it used to be done), and suddenly your code breaks because the Version 2 DOM won't load into a Version 3 DOM using the load() method.  And serializing the XML is pointless, because you should already *have* the data in XML form.

Now, this line here:
   xmlhttp.Open("POST", "http://xxxx/whatever.asp", false);

will generate the error you're talking about, if http://xxxx/whatever.asp is a different server than the one that served the page that this code is executing from.  The page the loads this code MUST be loaded from the local filesystem, not a remote server, for this to work.  Or else the remote server that provided this page must be "http://xxxx/"

So, Server "yyyy" sends a page to client.  

Page on client tries to POST to server "xxxx", but gets an error "page is trying to access data not under it's control"...

Regards,
Mike Sharp
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9629936
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...
0
 
LVL 25

Expert Comment

by:devic
ID: 9641613
Michel, did you try my suggestion?
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9642146
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
0
 
LVL 25

Expert Comment

by:devic
ID: 9642204
hi Mike,

before to send, i tried and for me, with FSO saving, works fine.
so my suggestion is working example.
0
 
LVL 25

Expert Comment

by:devic
ID: 9642332
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.
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 9642493
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
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 9642536
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
0
 
LVL 75

Author Comment

by:Michel Plungjan
ID: 10739196
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Preface This article introduces an authentication and authorization system for a website.  It is understood by the author and the project contributors that there is no such thing as a "one size fits all" system.  That being said, there is a certa…
Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now