XML .attributes not working - javascript

in an XML node that looks like this:
why would this code not work?
xml = $.parseXML( xml );
console.log(xml);
plot = $(xml).find("movie");
aP = plot.attributes
console.log(aP);
I am getting undefined for console log. aP
i also tried aP = $(plot).attributes

attributes is not a jquery property. Try plot.get(0).attributes this way you can use the attributes property on your element and not on a jquery object.
$(xml).find("movie"); //returns jquery object
$(plot) // is a jquery object of a jquery object. You really want your object to be a jquery object aye?
get(index): Description: Retrieve one of the elements matched by the
jQuery object.
In other words, your get returns an actual element.

Related

jQuery: get the normal JS format of a html element

I am using jQuery and everything works fine except a few stuff. There are a few things you cannot do with the jQuery format of an element but only with the simple JS format. Especially, when using the hasAttributes() in simple JS.
This works:
let fooDiv = document.getElementsByTagName("div")[0];
console.log(fooDiv.hasAttributes()); //returns false as expected
let barDiv = document.getElementsByTagName("div")[1];
console.log(barDiv.hasAttributes()); //returns true as expected
<div>foo</div>
<div id="id">bar</div>
This doesn't:
let fooDiv = $(document.getElementsByTagName("div")[0]) //creates a jQ object
console.log(fooDiv.hasAttributes()); //error
let barDiv = $(document.getElementsByTagName("div")[1]) //creates a jQ object
console.log(barDiv.hasAttributes()); //error
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>foo</div>
<div id="id">bar</div>
I am aware that the jQuery hasAttr() exists but I want to get the JS format of a jQuery object. There are a lot of differences, for example the jQuery creates an object but otherwise it is a html node list.
Initially, my question is:
How do I get the html node list or html element or the simple JS format of a html element(s) from jQuery?
To expand on what blex said in the comments ... when jQuery is used to select an HTML element, the raw HTML is always collected in an array as part of the variable you assign it to. For example, using your code:
// grab the element or elements
let fooDiv = $(document.getElementsByTagName("div")[0]);
// lets see the HTML!
consoe.log( fooDiv[0] );
The HTML itself will be exposed in that array, allowing direct access to the HTML and its properties... for example:
console.log( fooDiv[0].innerHTML );
or
console.log( fooDiv[0].tagName );

Correct jQuery Syntax for accessing text of array in one line

I am trying to access the text of the first "th" element of the first element of "rows" with jQuery and would like to do so in one line
var currentStation = $(rows[0]).find("th")[0].text();
What would be the correct syntax to do so?
I am able to get the "th" element, but as soon as I try to access the text I get error messages.
I already tried numerous variations of different brackets combinations, but each one threw me errors.
The issue is that your [0] on find("th") takes the HTML element out of the jQuery object. The easiest way to do this is to either use innerText instead of text:
var currentStation = $(rows[0]).find("th")[0].innerText;
Or don't use [0], rather first:
var currentStation = $(rows[0]).find("th:first").text();
(Or another first):
var currentStation = $(rows[0]).find("th").first().text();
text() is a method on jQuery objects.
You are extracting the DOM element object from the jQuery object and then trying to call text() on the DOM element object.
Use the :first selector instead (note this is a jQuery selector and not a CSS selector)
const $firstRow = $(rows[0]);
const $firstTh = $firstRow.find("th:first");
var currentStation = $firstTh.text();

Value is undefined when element is obtained with jQuery

Below is the code where I obtain my input element with jQuery:
var txt = $(tableRow).find('input:text');
if (txt.value == null) {
//TO DO code
}
and here's how I do it with pure JavaScript
var txt = document.getElementById('txtAge');
if (txt.value == null) {
//TO DO code
}
With the first way the value of the txt is undefined. But with the second way the value is what's inside the input element. Now more interesting is, on the bottom-right pane of the Mozilla Firebug if I scroll down to the "value" of the txt I can see it there, both ways.
I know I can simply say $(txt).val(), but I also want to understand why I can't access the value of an element if it's been selected by jQuery. Isn't jQuery just a library of JavaScript functions?
.value is not part of the jquery api. You should use .val() instead:
var txt = $(tableRow).find('input:text');
if (txt.val() == "") {
//TO DO code
}
A dom object and a jquery dom object are not exactly the same. In fact, you can open the Developer tools (in webkit) or Firebug (Firefox) to check what are they in the inside. Jquery holds more information (actually, it contains an instance of the dom that it's representing). So, if you wanted to use .value, you need to call the "generic" dom object from the jquery object, and then use .value.
jQuery selects DOM elements using various native and non-native techniques and places them all in it’s own array-like instance that also wraps them in their own API. jQuery doesn’t "extend" native DOM properties or methods, so you will need to target the DOM node to do that.
Think of it like this:
var node = document.getElementById('txtAge'); // the DOM node
var txt = $('#txtAge'); // the same node wrapped in a jQuery object/API
Since jQuery object holds an array-like collection of DOM nodes, so you can access the first element by doing:
txt[0] // same as node
But it’s generally recommended that you use the .get() method:
txt.get(0)
Another more jQuery-way to do what you want is to iterate through a jQuery collection using .each():
$(tableRow).find('input:text').each(function() {
// "this" in the each callback is the DOM node
if ( this.value == null ) {
// Do something
}
});
.find() will return an arry-like object. If you're sure that there's one, and one only, element matching your query, you could do
var txt = $(tableRow).find('input:text')[0].value;
That's not very jQuery-like, so to speak, more like a mismatch of both jQuery and DOM methods, but it'll get what you want. Also, since you show, as a DOM example, var txt = document.getElementById('txtAge');, this could be rewritten in jQuery as
var txt = $('#txtAge')[0];
var x = $(tableRow).find('input:text');
It's an jquery object .
`x.value`
There is no property value in jquery object . So it returns undefined.
x.val() is a method you can use for get the value of an element.

parsing XML in JavaScript, trying to get elements by classname

I am trying to parse a large XML file using JavaScript. Looking online, it seems that the easiest way to start is to use the browser's DOM parser. This works, and I can get elements by ID. I can also get the "class" attribute for those elements, and it returns what I would expect. However, I don't appear to be able to get elements by class.
The following was tried in the latest Chrome:
xmlString = '<?xml version="1.0"?>';
xmlString = xmlString + '<example class="test" id="example">content</example>'
parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString,"text/xml");
xmlDoc.getElementById("example");
// returns the example element (good)
xmlDoc.getElementById("example").getAttribute("class");
// returns "test" (good)
xmlDoc.getElementsByClassName("test");
// returns [] (bad)
Any ideas?
This should get all elements of a given class, assuming that the tag name will be consistent.
var elements = xmlDoc.getElementsByTagName('Example');
var classArray = [];
for(var i=0;i<elements.length;i++){
if(elements[i].className=="test"){
classArray.push(elements[i])
}}
You can use JQuery to parse an XML file by using a class selector. http://jquery.com
Updating the parser type to HTML as opposed to XML should work.
parser = new DOMParser();
xmlDoc = parser.parseFromString(xmlString,"text/html")

How do I parse nodes from an XML document into an HTML page using javascript?

I'm trying to list the Across and Down clues of a crossword puzzle from an XML feed, but can't figure out how to drill into the nodes. Here's a piece sample of the XML:
<across>
<a1 a="BLOC"
c="Group of like-minded voters"
n="1"
cn="1" />
<a2 a="BATOR"
c="Ulan ___, Mongolia"
n="6"
cn="5" />
<a3 a="OMEN"
c="Black cat, supposedly"
n="12"
cn="10" />
...
<down>
<d1 a="BLIPS"
c="Spots on a radar screen"
n="1"
cn="1" />
<d2 a="LIMIT"
c="Word at the express checkout aisle"
n="2"
cn="2" />
<d3 a="OMANI"
c="Man from Muscat"
n="3"
cn="3" />
<d4 a="CACKLE"
c="Laugh like the Wicked Witch"
n="4"
cn="4" />
I used the following method in my javascript:
document.getElementById('across_clues').innerText = xmlhttp.responseXML.getElementsByTagName('across')[0].childNodes;
document.getElementById('down_clues').innerText = xmlhttp.responseXML.getElementsByTagName('down')[0].childNodes;
I made two divs in my HTML ("#across_clues" and "#down_clues"), but this is what is rendered on my HTML page:
ACROSS
[object NodeList]
DOWN
[object NodeList]
I'm sure this is a rather simple error on my part, as I am very new to parsing XML with javascript, but what am I missing? Is there another call that I need to pass in to actually list the XML data? Please advise.
Thanks,
Carlos
UPDATED QUESTION
OK, so here's what I ran into in my second attempt to solve this problem:
I figured out how to pull in data from individual nodes...one at a time, but I can't figure out how to list an array of nodes all at once. I don't want to list every value in , , etc...only 'cn' and 'c' as a pair for each childNode of (same thing with ).
Here's my revised code:
var across = xmlhttp.responseXML.getElementsByTagName('across')[0].childNodes;
var down = xmlhttp.responseXML.getElementsByTagName('down')[0].childNodes;
var a1Node = xmlhttp.responseXML.getElementsByTagName('a1')[0];
var a2Node = xmlhttp.responseXML.getElementsByTagName('a2')[0];
var d1Node = xmlhttp.responseXML.getElementsByTagName('d1')[0];
var d1Node = xmlhttp.responseXML.getElementsByTagName('d2')[0];
document.getElementById('across_clues').innerText = a1Node.getAttribute('cn');
document.getElementById('across_clues').innerText = a1Node.getAttribute('c');
document.getElementById('down_clues').innerText = d1Node.getAttribute('cn');
document.getElementById('down_clues').innerText = d1Node.getAttribute('c');
RESULT:
Only one attribute renders into #accross_clues and one attribute in #down_clues. Each div only displays the last .getAttribute() call on the list...no matter how many I list. I also tried the function below, but still no success:
function getAcross() {
if (across) {
var acrossNodes = across.childNodes;
if (acrossNodes) {
for (var i = 0; i < acrossNodes.length; i++) {
var cnAttr = acrossNodes[i].getAttribute('cn');
var cAttr = acrossNodes[i].getAttribute('c');
document.getElementById('across_clues').innerText = cnAttr + '.' + cAttr;
}
}
}
}
Can anyone help me out with this? I am a serious novice when it comes to XML and childNodes. Your feedback is much appreciated.
Thanks,
Carlos
Here you are mentioning it as childNodes, this itself is an object and u have access the childNodes with the indexes, like childNodes[0], childNodes[1],..........
Hope this helps you
In your code you try assing XML DOM nodes collection (collection of nodes) to innerHTML property (string type). Additionaly, tags A1, A2 ... is not defined in html: what do you expect to get?
In my opinion you can do one from next (without using extrenal libs, only with javascript):
(bad way) With using javascript you can go starting from
xmlhttp.responseXML.documentElement and looping through all XML DOM
tree elements, attributes, values and create from it content HTML DOM
node tree. This root HTML DOM you can append with using appendChild()
to your document HTML DOM.
(true way) Second way is more proper. You need XSL document to transform your XML document to fragment with using importStylesheet() and transformToFragment() methods of XSLTProcessor object. This fragment you can easily append to your document HTML DOM with appendChild() method. -
For IE8 and less (for IE9 not tested) this above "true way" is not works because XSLTProcessor is not implemented. In IE you must use transformNode(stylesheet). This create HTML string and you can assing it to innerHTML property of your document HTML DOM node.
Update: XSLTProcessor can be not implemented in some mobile browsers.

Categories

Resources