0

I have an object that contains a listing of unique column names:

["heading", "startDate", "finishDate"]

I am returning an XML data set that looks like similar to this this:

<z:row ows_heading='Header' ows_startDate='1/1/2016' ows_finishDate='1/11/2016' ows_Description='Ignore me'/>
<z:row ows_heading='Header' ows_startDate='2/3/2016' ows_finishDate='2/12/2016' ows_Description='Ignore me'/>

How do I loop through the unique column name object to get the column name, append "ows_" to it and then find the resulting value and add it back to the object so that the end result is something like:

["heading": "Header", "startDate": "1/1/2016", "finishDate": "1/11/2016"]

EDIT: Current code block:

var a=[];var obj={};
        $(r).find("[nodeName=z:row]").each(function() 
        {
            $.each(uniqHeaderVals, function( key, value ) {
                var thisVal = $(this).attr("ows_"+value);
                obj.value = thisVal;
            });

            a.push(obj);
        });
        console.log(a);
1
  • Have you tried anything? Are you asking how to loop through an array? Commented Nov 30, 2016 at 22:08

4 Answers 4

1

Building on @ScottMarcus almost correct answer

var arry = ["heading", "startDate", "finishDate"];

var elems = document.getElementsByTagName("z:row");

var resultArry = [].map.call(elems, function(elem) {
  // For each element, create an object
  return arry.reduce(function(result, attr) {
    result[attr] = elem.getAttribute('ows_' + attr);
    return result;
  }, {});
});
console.log(resultArry);
<z:row ows_heading='Header' ows_startDate='1/1/2016' ows_finishDate='1/11/2016' ows_Description='Ignore me'/>
<z:row ows_startDate='2/3/2016' ows_finishDate='2/12/2016' ows_Description='Ignore me' ows_heading='Header' />

The difference with this code is that it uses the attribute name, rather than position

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

Comments

0

Just loop through the elements and for each one loop through its attributes and extract the attribute values?

Your result will need to be an array of objects though:

[ 
   { "heading": "Header", "startDate": "1/1/2016", "finishDate": "1/11/2016" },
   { "heading": "Header", "startDate": "2/3/2016", "finishDate": "2/12/2016" }
]

Since this: ["heading": "Header", "startDate": "1/1/2016", "finishDate": "1/11/2016"] is not a valid structure.

var arry = ["heading", "startDate", "finishDate"];

var elems = document.getElementsByTagName("z:row");

var resultArry = [];

// Loop through the XML elements
for(var i = 0; i < elems.length; ++i){
  
  // For each element, create an object
  var obj = {};
  
  // Loop through the element's attributes
  for(var x = 0; x < elems[i].attributes.length - 1; ++x){
    // For each attribute, create a property value
    obj[arry[x]] = elems[i].attributes[x].value;
  }
  resultArry.push(obj);
}

console.log(resultArry);
<z:row ows_heading='Header' ows_startDate='1/1/2016' ows_finishDate='1/11/2016' ows_Description='Ignore me'/>
<z:row ows_heading='Header' ows_startDate='2/3/2016' ows_finishDate='2/12/2016' ows_Description='Ignore me'/>

4 Comments

your code is flawed if the order of the attributes in a z:row is different to the order in arry
True, but since the OP told us what the XML schema is, my code is not flawed.
the schema doesn't dictate the order of attributes
I understand, but you miss the point. I am taking the OP at his word and providing a solution based on that.
0

const XML_INPUT = `
<z:row ows_heading='Header' ows_startDate='1/1/2016' ows_finishDate='1/11/2016' ows_Description='Ignore me'/>
<z:row ows_heading='Header' ows_startDate='2/3/2016' ows_finishDate='2/12/2016' ows_Description='Ignore me'/>`;
const COLUMNS = ['heading', 'startDate', 'finishDate'];

console.log(children(toDom(XML_INPUT)).reduce(toRow, []));

function toDom(str) {
    var tmp = document.createElement('div');
    tmp.innerHTML = str;
    return tmp;
}

function children(nodes) {
  return [...nodes.querySelectorAll('*')];
}

function toRow(p, node) {    
    p.push(COLUMNS.reduce((p, c) => {
        p[c] = attr(node, c);
        return p;
    }, {}));
    return p;
}

function attr(node, name) {
    return node.getAttribute('ows_' + name);
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

If I understand correctly, you have the xml string in a variable. In that case, you could do it like this:

var uniqHeaderVals = ["heading", "startDate", "finishDate"]

var xml = "<z:row ows_heading='Header' ows_startDate='1/1/2016' ows_finishDate='1/11/2016' ows_Description='Ignore me'/>"
    + "<z:row ows_heading='Header' ows_startDate='2/3/2016' ows_finishDate='2/12/2016' ows_Description='Ignore me'/>";

var r = $('<content>' + xml + '</content>'); // valid XML needs a single root

var a = r.find('z\\:row').get().map(function (node) {
    return uniqHeaderVals.reduce( function (o, title) {
        var attr = $(node).attr('ows_' + title);
        if (attr) o[title] = attr;
        return o;
    }, {})
});

console.log(a);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Comments

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.