Asked  10 Months ago    Answers:  5   Viewed   11 times

I tried to

1) load an xml file using javascript as an object, say note.xml

2) then save the object to a new xml file, say note_new.xml

I did 1) but failed 2)

I tried to use method save() to do 2). After my failure, I checked ms site and they said save() is not supported....

could some one enlighten me how to do the save?

thank you!

here is the code:

<html>
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<h1>W3Schools Internal Note</h1>
<p><b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span>

<script type="text/javascript">
if (window.ActiveXObject){
alert("there is ActiveXObject");
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false; 
xmlDoc.load("note.xml"); 
}else{
alert("i am not withActiveXObject!");
xhttp=new XMLHttpRequest();
xhttp.open("GET","note.xml",false);
xhttp.send("");
xmlDoc=xhttp.responseXML;
}
xmlDoc.save("note_new.xml"); 
</script>

</body>
</html>

update:

seems this is related to security issue. I appologize to those experienced programmers for my putting this question in a rush because it seems a newbie question.

 Answers

2

Your problem is: javaScript does not have an input/output (I/O) API as it is a client-side scripting language and consequently has no access to the file system via the server. You would need to use a server-side scripting language to save data to a server. There may be hacks to solve your problem client-side, but they are probably either unsave or otherwise buggy. (btw: what api is the save method member of? Did you make that up?)

What you can do is save data temporarily to any DOM element (e.g. window, or a javaScript) object. There is however no way to make these changes permanent.

In your case, looking in to PHP scripting might be the best way to go.

Thursday, August 12, 2021
 
hillz
 
3

The following will work in all major browsers, including IE 6:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    parseXml = function(xmlStr) {
        return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
       new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(xmlStr) {
        var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlStr);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

Example usage:

var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);

Live demo:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    parseXml = function(xmlStr) {
        return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
       new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(xmlStr) {
        var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlStr);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

var xml = parseXml("<foo>Stuff</foo>");
document.body.innerHTML = "Root element: " + xml.documentElement.nodeName;
Tuesday, June 1, 2021
 
Vlad
 
2

Readium Foundation just released Readium Web Components: see http://readium.org/news/announcing-readiumjs-a-javascript-library-for-browser-based-epub-3-reading (code: https://github.com/readium/Readium-Web-Components )

Alternatively, you might want to have a look at FuturePress: http://www.futurepress.org/ (code: https://github.com/fchasen/epub.js/ )

Finally, TEA also has something you might find interesting: https://github.com/TEA-ebook/teabook-open-reader

Wednesday, August 11, 2021
 
3

You want tagName, which is the name of the element. (Sorry about that, for Elements, tagName and nodeName are the same.)

The problem is that the first child of your myParent element isn't the myChild element, it's a text node (containing whitespace). Your structure looks like this:

  • Element "myParent"
    • Text node with a carriage return and some spaces or tabs
    • Element "myChild"
      • Text node with "content"
    • Text node with a carriage return and some spaces or tabs
  • Element "myParent"
    • Text node with a carriage return and some spaces or tabs
    • Element "myChild"
      • Text node with "content"
    • Text node with a carriage return and some spaces or tabs

You need to navigate down to the actual myChild element, which you can do with getElementsByTagName again, or just by scanning:

var x=xmlDoc.getElementsByTagName("myParent");
var c = x[1].firstChild;
while (c && c.nodeType != 1) { // 1 = ELEMENT_NODE
    c = c.nextSibling;
}
alert(c.nodeName); // "myChild"

Note that Elements don't have a meaningful nodeValue property; instead, you collect their child text nodes. (More in the DOM specs: DOM2, DOM3.)

Also note that when indexing into a NodeList, the indexes start at 0. You seem to have started with 1; ignore this comment if you were skipping the first one for a reason.


Off-topic: It's always best to understand the underlying mechanics of what you're working with, and I do recommend playing around with the straight DOM and referring to the DOM specs listed above. But for interacting with these trees, a good library can be really useful and save you a lot of time. jQuery works well with XML data. I haven't used any of the others like Prototype, YUI, Closure, or any of several others with XML, so can't speak to that, but I expect at least some of them support it.

Wednesday, August 25, 2021
 
5

You have the option of iterating over the xml nodes directly, employing one of the XPath processing APIs. It basically suffices to rewrite your showTheList function. What follows is a complete standalone solution, however:

<html>
    <head>
    <title>Report</title>
    <style>

    </style>
    <script>
        function showTheList() {
            let x_xmlisland = document.getElementById("template_xml");
            let s_xmlsource = x_xmlisland.textContent; 

            // Parse xml. This may beunnecessary depending on the ajax lib used. 
            let parser = new DOMParser();
            let xmlDoc = parser.parseFromString(s_xmlsource, "application/xml");

            // Obtain the xml node set containing the needed info.
            // In this case, these are the textual contents of all 'Time' elements that are children of a 'Step' node.
            let xpr_time  = xmlDoc.evaluate("//Step/Time/text()", xmlDoc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            let node_time
              ;

            let divBooks = document.getElementById('books');        // THE PARENT DIV.
// debugger; // uncomment for tracing 
            while ( ( node_time = xpr_time.iterateNext() ) !== null ) { // iterate over xml nodes
                let divLeft = document.createElement('div');
                divLeft.className = 'col1';
                divLeft.innerHTML = node_time.textContent;  // The xpath expression references the 'text()' function which provides a text node. String must still be extracted. 
                divBooks.appendChild(divLeft);
            }
        }
        </script>
    </head>
    <body onLoad="showTheList()">
        <script type="text/xml" id="template_xml"><?xml version="1.0"?>
<Steps>
    <Step rID="T6">
        <Obj ><![CDATA[Get Data Table - Passed]]></Obj>
        <Details ><![CDATA[]]></Details>
        <Time><![CDATA[7/5/2018 - 13:16:26]]></Time>
        <TimeTick>1530810986</TimeTick>
        <NodeArgs eType="User" icon="5" nRep="9" >
            <Disp><![CDATA[Get Data Table - Passed]]></Disp>
        </NodeArgs>
    </Step>
    <Step rID="T7">
        <Obj ><![CDATA[GetDataTable - Successful]]></Obj>
        <Details ><![CDATA[Toral Row get:65534]]></Details>
        <Time><![CDATA[7/5/2018 - 13:16:27]]></Time>
        <TimeTick>1530810986</TimeTick>
        <NodeArgs eType="User" icon="5" nRep="10" status="Passed" >
            <Disp><![CDATA[GetDataTable - Successful]]></Disp>
        </NodeArgs>
    </Step>
</Steps>
        </script>
        <p>Results of  <b>Test cases</b> </p>
        <div id="books"></div>
    </body>
</html>

Code has been tested.

Note

The sample xml provided in the question is not well-formed since it lacksa unique root element. The solution would still work but only consider the first Stepelement.

Update

To allow for xml from an external source, the ajax code needs to be reintroduced:

function getData() {
    let oXHR = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
    oXHR.onreadystatechange = function() {
        if (oXHR.readyState == 4 && oXHR.status == 200) {
            showTheList(oXHR);
        }
    };
    oXHR.open("GET", "state_data.xml", true); // ...or whatever else
    oXHR.send();
} // getData

Lacking local data, it makes no longer sense to register showTheList as an onLoad handler.

<body onLoad="getData()">
Tuesday, December 14, 2021
 
AndiDog
 
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :