I am parsing XML via libxmljs2 and then trying to add an extra element, see example below.
var x = require('libxmljs2');
var xmlDoc = x.parseXmlString(`<?xml version="1.0" encoding="UTF-8"?>
<ns:FOO xmlns:ns=“example ns" xmlns:ns2="example ns 2”>
<ns:A>
<ns2:X>TEXT</ns2:X>
</ns:A>
<ns:B>
<ns2:Y>TEXT</ns2:Y>
<ns2:Z>TEXT</ns2:Z>
<ns2:P>TEXT</ns2:P>
</ns:B>
</ns:FOO>`)
What i want is to make it like:
<?xml version="1.0" encoding="UTF-8"?>
<ns:FOO xmlns:ns=“example ns" xmlns:ns2="example ns 2">
<NEW-ELEMENT>
<NEW-SUB-ELEMENT>
<ANOTHER-NEW-SUB-ELEMENT>TEXT</ANOTHER-NEW-SUB-ELEMENT>
<NEW-SUB-ELEMENT>
</NEW-ELEMENT>
<ns:A>
<ns2:X>TEXT</ns2:X>
</ns:A>
<ns:B>
<ns2:Y>TEXT</ns2:Y>
<ns2:Z>TEXT</ns2:Z>
<ns2:P>TEXT</ns2:P>
</ns:B>
</ns:FOO>
This is what I am trying to do:
const reqNode = xmlDoc.get('//ns:FOO', { FOO: 'example'})
const doc = new x.Document();
doc
.node('NEW-ELEMENT')
.node('Service', "TI")
.parent()
.node('NEW-SUB-ELEMENT')
.node('ANOTHER-NEW-SUB-ELEMENT', 'TEXT')
.parent()
.parent().toString()
reqNode.addChild(doc)
However it seems to make it like:
<?xml version="1.0" encoding="UTF-8"?>
<ns:FOO xmlns:ns=“example ns" xmlns:ns2="example ns 2">
<ns:A>
<ns2:X>TEXT</ns2:X>
</ns:A>
<ns:B>
<ns2:Y>TEXT</ns2:Y>
<ns2:Z>TEXT</ns2:Z>
<ns2:P>TEXT</ns2:P>
</ns:B>
<NEW-ELEMENT>
<NEW-SUB-ELEMENT>
<ANOTHER-NEW-SUB-ELEMENT>TEXT</ANOTHER-NEW-SUB-ELEMENT>
<NEW-SUB-ELEMENT>
</NEW-ELEMENT>
</ns:FOO>
Any ideas, where I'm doing wrong?
Much appreciated
node(...) always adds the node at the end. If you want to insert an element elsewhere you can use addPrevSibling(siblingNode) to insert a node before the Element that was called on. So here you would first find the ns:A Element and then call that function on it (you probably have to construct the child element explicitly so it can be passed as an argument).
Related
I have one sample XML & XSL resource. I am getting XML as a string from API call in javascript. While XSLT is present as a static resource on the server. My goal is to display XML content along with stylesheet in HTML document element.
I do not want to use XSLTProcessor for now. I would like to try the browser way. And yes both the XML and XSLT would be coming from the same server.
Code:
import XSL from '#salesforce/resourceUrl/Roles';
export default class DisplayReport extends LightningElement {
renderedCallback(){
var xml = '<root> <node>one</node> <nodes> <node>1</node> <node>2</node> </nodes> <node>two</node> </root>';
var output = '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="'+XSL+'" ?>'+xml;
console.log(output); //output on below line
//<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/assets/project/b481ca5a6f/staticresources/Roles" ?><root> <node>one</node> <nodes> <node>1</node> <node>2</node> </nodes> <node>two</node> </root>
var xmlNode = this.parseXml(output);
console.log(xmlNode);
const element = this.template.querySelector('div.dms');
element.appendChild(xmlNode.documentElement);
}
parseXml(xmlStr){
if (window.DOMParser) {
return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
}
}
}
Markup:
<template>
<div class="dms" lwc:dom="manual">
</div>
</template>
Output: (no style sheet getting applied)
one 1 2 two
Any idea what is missing here?
I have the following XML (it's actually a gpx file)
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<gpx version="1.1" creator="Movescount - http://www.movescount.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.cluetrust.com/XML/GPXDATA/1/0 http://www.cluetrust.com/Schemas/gpxdata10.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns:gpxdata="http://www.cluetrust.com/XML/GPXDATA/1/0" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns="http://www.topografix.com/GPX/1/1">
<trk>
<name>Move</name>
<trkseg>
<trkpt lat="52.3535" lon="4.848642">
<ele>12</ele>
<time>2017-05-05T06:25:41.000Z</time>
<extensions>
<gpxtpx:TrackPointExtension xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">
<gpxtpx:hr>105</gpxtpx:hr>
</gpxtpx:TrackPointExtension>
<gpxdata:cadence>81</gpxdata:cadence>
<gpxdata:temp>22.7000007629395</gpxdata:temp>
<gpxdata:distance>-19.1377588523053</gpxdata:distance>
<gpxdata:altitude>12</gpxdata:altitude>
<gpxdata:seaLevelPressure>1024</gpxdata:seaLevelPressure>
<gpxdata:speed>3.20000004768372</gpxdata:speed>
<gpxdata:verticalSpeed>0</gpxdata:verticalSpeed>
</extensions>
</trkpt>
</trkseg>
</trk>
</gpx>
I load it via:
var parser = new DOMParser();
xmlDocument = parser.parseFromString(xml, 'application/xml');
This works:
xml.getElementsByTagName('gpx')
>[gpx]
But this does not
xml.getElementsByTagName('gpxdata:distance')
>[]
Although I see that its tag name is gpxdata:distance in the chromewebtools.
The Standart says:
The getElementsByTagName(qualifiedName) method, when invoked, must
return the list of elements with qualified name qualifiedName for
context object.
What am I missing?
gpxdata:distance is not a tag name.
gpxdata is a namespace. distance is a tag name.
xml.getElementsByTagNameNS(
"http://www.garmin.com/xmlschemas/TrackPointExtension/v1",
"distance"
);
OK, I have an XML/XSLT pairing (inserted into my HTML via Javascript from 2 external files) that creates a button on the page with the nodeValue taken from a tag called 'JobID' (a generated GUID).
<button id="5f8294ca-fe5a-4da9-847b-da99df999000" onclick="markFinished(this.id)" type="button">Finished</button>
Thus returning the id of the button to a function...
function markFinished(clicked_id)
{
cid = clicked_id;
document.write(cid)
}
The XML look like this...
<?xml version="1.0" encoding="utf-8"?>
<CurrentJobs>
<Job>
<JobID>25657287-cc52-415b-8781-be37d5098656</JobID>
<Status>a-current</Status>
</Job>
<Job>
<JobID>5f8294ca-fe5a-4da9-847b-da99df999000</JobID>
<Status>a-current</Status>
</Job>
<Job>
<JobID>05a84779-5801-4645-a7f9-74529ea5298b</JobID>
<Status>a-current</Status>
</Job>
<Job>
<JobID>07df3deb-4935-4504-8822-a73ccea038ae</JobID>
<Status>b-complete</Status>
</Job>
<Job>
<JobID>078c496d-ac60-48e7-b9fe-a0e1f78ff2c5</JobID>
<Status>c-upcoming</Status>
</Job>
<Job>
<JobID>07ec868e-d294-4bb3-807d-00df66f5bab2</JobID>
<Status>c-upcoming</Status>
</Job>
<Job>
<JobID>8bdeee5f-2bf6-4e44-8af8-69f600048dfe</JobID>
<Status>a-current</Status>
</Job>
</CurrentJobs>
I need a way for my function to match the clicked_id to the JobID and replace the nextSibling (Status) with 'b-finished'. Any help here would be greatly appreciated.
You'd do that by parsing the XML and traversing it nodes.
As the value you're looking for is the text, you have to iterate and check each element until a match is found, then get the next element and replace the text content of that
var parser = new DOMParser();
var doc = parser.parseFromString(xml, "application/xml");
function markFinished(clicked_id) {
var cid = clicked_id;
var nodes = doc.getElementsByTagName('JobID'),
match = null;
for (var i=nodes.length; i--;) {
if ( nodes[i].textContent.trim() === clicked_id ) {
match = nodes[i];
break;
}
}
if (match) {
match.nextSibling.textContent = 'b-finished'
}
}
FIDDLE
I want to parse OpenSearch XML to get a url for search like "http://stackoverflow.com/search?q={searchTerms}"
the XML is like this:
<?xml version="1.0" encoding="UTF-8" ?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>Stack Overflow</ShortName>
<Description>Search Stack Overflow: Q&A for professional and enthusiast programmers</Description>
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16" type="image/x-icon">http://sstatic.net/stackoverflow/img/favicon.ico</Image>
<Url type="text/html" method="get" template="http://stackoverflow.com/search?q={searchTerms}"></Url>
</OpenSearchDescription>
var domParser = new DOMParser,
dom = domParser.parseFromString(xml, "application/xml");
console.log( dom.getElementsByTagName("Url")[0].getAttribute("template"));
//"http://stackoverflow.com/search?q={searchTerms}"
Just let the XmlHttpRequest do the work? I'm quite sure you don't get the XML as a string.
var dom = xhr.responseXML;
var url = dom.documentElement.querySelector("Url[template]"); // DOM lvl 3!
if (url)
return url.getAttribute("template");
This is my exact xml file:
<?xml version="1.0" ?>
<blah_de_blah>
<unblocker_details table_color="#F2F0FF" type="zip" alt_link="http://g.org/288"
link_for_deletion="3-QQ5DJoa-AWFT7a9" comment="zippy" />
<unblocker_details table_color="#FFFFFF" type="Webpage" alt_link="http://www.gg.com"
link_for_deletion="4-rOX2brr-2qQeGY3" comment="test" />
</blah_de_blah>
I have successfully gotten it via an ajax request, then did this:
var xmlDoc=null;
var parser = new DOMParser();
xmlDoc = parser.parseFromString(data, "text/xml");
and now I need to get each of those values from unblocker_details into a variable:
for example:
the_table_color=table_color;
the_type =type;
etc
Please also check if I declared the xml properly as I am very new to this.
Thanks!
Something like this:
var nodes = xmlDoc.getElementsByTagName("unblocker_details");
for(i=0; i< nodes.length; i++) {
the_table_color = nodes[i].getAttribute("table_color");
// get other attributes the same way
}
You can use this http://www.w3schools.com/ajax/ajax_xmlfile.asp