0

I have an XML which I am parsing using jquery, it works but I want to only get part of the XML data and then save all that part in localstorage.

My xml looks like this

<channel id="123"><display-name>123</display-name></name></channel>
<channel id="123"><display-name>123</display-name></name></channel>
<channel id="123"><display-name>123</display-name></name></channel>
<programme id="123"><display-name>123</display-name></name></programme>
<programme id="123"><display-name>123</display-name></name></programme>
<programme id="123"><display-name>123</display-name></name></programme>

But I only want to get all the <programme> data and then save that to localstorage. Im not sure how I can only grab the programme sections.

I have tried saving the whole xml but that didnt seem to output any data. This is what what I have tried.

<div id="text"></div>

$(function(){

  $.ajax({
    type: "GET",
    url: "/myxml",
    dataType: "xml",
    success: function(xml){

window.localStorage.setItem('fullxml', xml)
$("#text").append(window.localStorage.getItem('fullxml'));

  },
  error: function() {
    alert("An error occurred while processing XML file.");
  }
  });
});
2
  • Try to console logging the result in the ajax success function. Do you get any response? Commented Aug 19, 2018 at 11:56
  • xml is an xml document, assuming everything else is working, so you can traverse it with jquery, eg $(xml).find("programme") Commented Aug 19, 2018 at 12:02

2 Answers 2

3

To get a specific node from an XML document, you can select the XML node like this:

Javascript:

var programmeNodes = fullxml.getElementsByTagName('programme');

jQuery:

var programmeNodes = $(fullxml).find('programme');

My Solution:

This solution grabs all <programme> nodes and saves the data into an array and then stores that array in local storage for later use.

Given XML data like this:

var xml = `
    <programmes>
        <programme id="1">
            <display-name>Test 1</display-name>
        </programme>
        <programme id="2">
            <display-name>Test 2</display-name>
        </programme>
  </programmes>
`;

Will give an array of objects like this which can then be stored.

[
    {
        id: 1,
        name: Test1
    },
    {
        id: 2,
        name: Test2
    }
]

Full demo code:

var xml = `
    <programmes>
        <programme id="1">
            <display-name>Test 1</display-name>
        </programme>
        <programme id="2">
            <display-name>Test 2</display-name>
        </programme>
    </programmes>
`;

var fullxml = $.parseXML(xml);

// find <programme> XML elements

var programmeNodes = $(fullxml).find('programme');

// create array for programme data

var programmesArr = [];

// loop through each programme and store data in array

$.each(programmeNodes, function(i) {
    var programmeID = $(programmeNodes[i]).attr('id');
  var programmeDisplayName = $(programmeNodes[i]).find('display-name').text();
  programmesArr.push({
    id: programmeID,
    name: programmeDisplayName
  });
});

// store programmesArr in local storage
// localStorage only allows strings, so we need to convert array to JSON string

localStorage.setItem('programmes', JSON.stringify(programmesArr));

// get programmes from local storage

var storedProgrammes = JSON.parse(localStorage.getItem('programmes'));

DEMO: https://jsfiddle.net/1nLw7hjr/13/

Usage:

var programmeToFind = 2;

var programme = $.grep(storedProgrammes, function(e) {
    return e.id == programmeToFind;
});

console.log(programme[0].id); // 2
console.log(programme[0].name); // Test2

Or as a little function:

function searchProgrammes(id) {
    var programme = $.grep(storedProgrammes, function(e) {
        return e.id == id;
    });
    return programme[0];
}

var programme = searchProgrammes(2);

console.log(programme.id); // 2
console.log(programme.name); // Test2

grep()

Finds the elements of an array which satisfy a filter function. The original array is not affected.

Sign up to request clarification or add additional context in comments.

11 Comments

Thanks that works, using the method to get the data back out, how could I filter the data to get the "id" of a programme node?
Actually the json data is just showing {} nothing is inside each object
its like this {"0"}:{}, {"2"}:{}, {"3"}:{}, etc
@brandbei37 - I updated my answer to demonstrate a better way.
yes that works now and if i wanted to grab all the data from a certain id, how do i output it? so if the id was "channel1" how could i output all channel 1 data?
|
0

I think you don't get any response because when you append the XML to the document, the browser try to parse it, and because this isn't valid HTML, it fails and show only the text, not the tags. So, the simplest solution will to not use jQuery's append() method, and instead, append the XML via text() (that doesn't parse the HTML tags, and instead escapes them), like:

$(function() {
  $.ajax({
    type: "GET",
    url: "/myxml",
    dataType: "xml",
    success: function(xml) {
      window.localStorage.setItem('fullxml', xml);
      var el = $("#text");
      el.text(el.text() + window.localStorage.getItem('fullxml'));
    },
    error: function() {
      alert("An error occurred while processing XML file.");
    }
  });
});

Edit:

If you want to store only some elements, you should convert the XML to objects. Use DOMParser, as follows:

$(function() {
  $.ajax({
    type: "GET",
    url: "/myxml",
    dataType: "xml",
    success: function(xml) {
      var xmldoc;

      if (window.DOMParser) {
        parser = new DOMParser();
        xmldoc = parser.parseFromString(xml, "text/xml");
      } else { // Internet Explorer
        xmldoc = new ActiveXObject("Microsoft.XMLDOM");
        xmldoc.async = false;
        xmldoc.loadXML(xml);
      }

      var programmes = xmldoc.getElementsByTagName('programme');
      var str = '';
      programmes.forEach(function(el) {
        str += el.outerHTML;
      });
      // str now contains only the <programme> elements
      window.localStorage.setItem('fullxml', str);
      var el = $("#text");
      el.text(el.text() + window.localStorage.getItem('fullxml'));
    },
    error: function() {
      alert("An error occurred while processing XML file.");
    }
  });
});

2 Comments

How can I just save the <programme> nodes using this? at the moment it works, but its saving the whole xml, i tried adding, fullxml.getElementsByTagName('programme') but it didnt work
This is didn't work because fullxml is a string, not a DOM element. But you can convert it to a dom element - I'll edit my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.