0

We have a webapp (standard Spring MVC, Java) - that I've written - that returns a response to our client (browser) as XML. The response is marshalled using JAXB and so on.

Within the ui - to interact with 3rd party software we need to pass part of the XML as is into a javascript method.

I.e everything from '<' in thirdPartyStuff to the final closing '>' - needs to be extracted.

After umpteen attempts and much debugging - I've come to a conclusion that this is the wrong way to do this. I believe I should wrap that part of the response in CDATA and extract it as .text() on what ever object... currently we're using jquery... the response comes back on an AJAX call...

But maybe it can be done .. currently we're tripping over trying to call .html() on an element - which as its XML - falls in a heap.

TIA.

:-)

Below is the kind of response structure app data for "us" and 'xml' for the third part. Only (& including) from " ... to " - needs to be extracted and passed as is (text string) to a 3rd party method.

<xml>
  <someNode>
     <ourStuff veryUseful="true"/>
     <thirdPartyStuff a="1" b="2">
       <moreStuff/>
       <evenMoreStuff/>
     </thirdPartyStuff>
  </someNode>


</xml>

Below is a failing test, basically illustrating my ignorance. So of course the console.log must fail.

In reality the data comes back via an $.ajax() call - but this test illustrates the behaviour. It generates a "Uncaught TypeError: Cannot call method 'replace' of undefined " - as there is no innerHtml on an XML "node" - which of course I believe is absolutely correct, and documented as such on the jquery API docs.

Note - this fails for me in Chrome & IE on Windows, but works on Firefox (Mac OS)... :-|

 <html>

<head>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>

    <script type="text/javascript">

        function hackit() {
            var data = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                    "<xml>" +
                    "<thirdParty>" +
                    "<blah a=\"0\" b=\"0\">" +
                    "</blah>" +
                    "</thirdParty>" +
                    "</xml>";

            $xmlData = $.parseXML(data);
            $data = $($xmlData);
            var thing = $data.find("thirdParty");

            console.log(thing.html());

        }
    </script>
</head>
<body onload="hackit()">

Loaded.

</body>
</html>

I think I will end up going this route.

https://stackoverflow.com/a/14197860/366073

Community
  • 1
  • 1
David Victor
  • 830
  • 9
  • 29
  • Java != Javascript :) – Pradeep Simha Oct 08 '13 at 17:26
  • More importantly, XML != HTML. It would make sense to use JS to check through the XML for the information you need and display that, but I don't know what you would expect to happen by calling .html(). Maybe you could clarify what you're doing at that step? How does HTML enter into this? – Katana314 Oct 08 '13 at 17:29
  • 2
    it doesn't, he wants to get the string form of the contents of someNode so that it can be sent. the closest method to that in jQuery of course is .html, hence why he attempted it. – Kevin B Oct 08 '13 at 17:32
  • I understand that, but I wasn't sure what was meant by this last part; "currently we're tripping over trying to call .html() on an element". What is calling .html() with the XML, and why? – Katana314 Oct 08 '13 at 17:34
  • Can you include in your question what you have actually attempted? I see hints of what you've tried but a full example would be far more useful. – Kevin B Oct 08 '13 at 17:34
  • Yes, quite aware of differences between Java, Javascript, XML, html .. hence the question. Have found lots of wrong ways to do this. :-) Just wish to know if there is a way using built in JS functions or library like JQuery to do this. I don't think there is. – David Victor Oct 08 '13 at 18:13
  • 1
    Added a working... failing test illustrating the wrong trees I'm barking up. :-) – David Victor Oct 08 '13 at 18:29
  • possible duplicate of [How can i get the entire xml node with javascript under Chrome?](http://stackoverflow.com/questions/13192814/how-can-i-get-the-entire-xml-node-with-javascript-under-chrome) – David Victor Oct 09 '13 at 07:37

1 Answers1

0

The answer here works for me. https://stackoverflow.com/a/13193743/366073

( See also: https://stackoverflow.com/a/43468/366073 ) I will spend some time studying why this works, but assume we are iterating over nodes and then simply serializing them.

To sum up the issue was not "extracting" the node, it was the approach to obtaining a string representation of the selection aka serialising it - that was wrong.

Have tested using the snippet below in IE, FF & Chrome and expected results obtained. Will now generalise this into our app. Have gone with the approach below & is now working in our app...

<html>

<head>
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>

    <script type="text/javascript">

        function serializeXmlNode(xmlNode) {
            if (typeof window.XMLSerializer != "undefined") {
                return new window.XMLSerializer().serializeToString(xmlNode);
            } else if (typeof xmlNode.xml != "undefined") {
                return xmlNode.xml;
            }
            return "";
        }


          function hackit() {

        var data = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
                "<xml>" +
                "<ourStuff>" +
                "<blah a=\"x\" b=\"y\">" +
                "</blah>" +
                "</ourStuff>" +
                "<thirdParty>" +
                "<blah a=\"0\" b=\"0\">" +
                "</blah>" +
                "</thirdParty>" +
                "</xml>";

        var xmlData = $.parseXML(data);

        var thirdPartyNode = $(xmlData).find("thirdParty blah")[0];
        console.log(serializeXmlNode(thirdPartyNode));

        var ourNode = $(xmlData).find("ourStuff blah")[0];
        console.log(serializeXmlNode(ourNode));

    }
    </script>
</head>
<body onload="hackit()">

Loaded.

</body>
</html>
Community
  • 1
  • 1
David Victor
  • 830
  • 9
  • 29