I am trying to get child node, but it prints null.
My code:
function findFile(ICO){
var fileName = ICO + '.xml';
const folderFiles = DriveApp.getFolderById('folderID').getFiles();
while (folderFiles.hasNext()) {
var folderFile = folderFiles.next();
if(folderFile.getName() == fileName){
return folderFile.getId();
break;
}
}
}
function filesearch(ICO){
var fileId = findFile(ICO);
var fileFound = DriveApp.getFileById(fileId).getBlob().getDataAsString();
var rawXml = XmlService.parse(fileFound);
return rawXml;
}
function parseXML(){
var text_ICO_txt = '27074358';
var docXml = filesearch(text_ICO_txt);
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Ares_odpovedi');
Logger.log(child1);
}
It prints:
[Element: <are:Ares_odpovedi [Namespace: http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0]/>]
null
So I tried different variation of Ares_odpovedi (including the whole text after Element:), but child node is null.
XML file:
<are:Ares_odpovedi xmlns:are="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0" odpoved_datum_cas="2022-05-09T15:00:10" odpoved_pocet="1" odpoved_typ="Vypis_VREO" vystup_format="XML" xslt="klient" validation_XSLT="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_odpovedi.xsl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0 http://wwwinfo.mfcr.cz/ares/xml_doc/schemas/ares/ares_answer_vreo/v_1.0.0/ares_answer_vreo.xsd" Id="ares">
<are:Odpoved>
<are:Pomocne_ID>0</are:Pomocne_ID>
<are:Vysledek_hledani>
<are:Kod>1</are:Kod>
</are:Vysledek_hledani>
<are:Pocet_zaznamu>1</are:Pocet_zaznamu>
<are:Vypis_VREO>
<are:Uvod>
<are:Nadpis>Výpis z veřejného rejstříku v ARES - elektronický opis</are:Nadpis>
<are:Aktualizace_DB>2022-05-09</are:Aktualizace_DB>
<are:Datum_vypisu>2022-05-09</are:Datum_vypisu>
<are:Cas_vypisu>15:00:09</are:Cas_vypisu>
<are:Typ_vypisu>aktualni</are:Typ_vypisu>
</are:Uvod>
<are:Zakladni_udaje>
...
Could you, please, hint me, how to deal with it?
Thank you in advance!
This answer supposes the modification of your showing script.
When I saw your XML data, it seems that the tag of Ares_odpovedi is the root element. So, for example, when you want to retrieve the element of Odpoved, please modify it as follows.
From:
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Ares_odpovedi');
Logger.log(child1);
To:
var root = docXml.getRootElement();
Logger.log(root);
var child1 = root.getChild('Odpoved', root.getNamespace());
Logger.log(child1);
Reference:
getChild(name, namespace)
Related
I'm trying to create a basic WYSIWYG editor where I can click on elements in a sidebar and have those element written to an iFrame page.
My current setup has me creating an array of JSX elements that I then write to a react-iframe via a contentDocument write call.
The problem is that right now when I attempt to add these components, I get an [object Object] printed in the iFrame. Attempting to JSON.stringify() said object only gives me a literal printout of the object and not a render of the JSX element itself.
Please give me constructive criticism and any ideas on better ways to go about this- this has been my naïve attempt based on what I currently know.
Code:
SetIFrameInnerHTML(){
//get snapshot from React's state
const snapshot = this.state.PagesSnapshot;
//if the snapshot exists
if(snapshot){
const currPage = document.querySelector('#page_selector').value;
//Variable I'll be storing array to print to page will be
var pageTags = [];
//Fetching data from my dB and setting variables...
snapshot.forEach(function (childSnapshot){
let testValue = childSnapshot.val();
if(currPage == Object.keys(testValue.pages)[0]){
const currPage = document.querySelector('#page_selector').value;
console.log('break');
var tagType_pt1 = testValue.pages
var tagType_pt2 = tagType_pt1[currPage];
var tagType = tagType_pt2.tags[0].tag_type;
var tagStyle_pt1 = testValue.pages
var tagStyle_pt2 = tagStyle_pt1[currPage];
var tagStyle = tagStyle_pt2.tags[0].style;
var tagContent_pt1 = testValue.pages;
var tagContent_pt2 = tagContent_pt1[currPage];
var tagContent = tagContent_pt2.tags[0].content;
if(tagType == 'p'){
pageTags.push(<p style = {tagStyle}>{tagContent}</p>);
}else if(TagType == 'img'){
pageTags.push(<img src = {imageSrc}></img>);
}
}
});
let editorFrame = document.getElementById('iFrameId');
// also tried: editorFrame.postMessage(pageTags, 'http://localhost:8080/', false);
editorFrame.contentDocument.write(pageTags);
//also tried: editorFrame.contentDocument.write(JSON.stringify(pageTags));
}
}
//Rendering the iframe
render(){
return(
<div>
... some JSX tags
<Iframe
id = "VisualEditorWindow"
url = {this.props.CurrentEditPageHandle}
ref = {this.VisualLogic}
width = "calc(100vw - 500px)"
height = "90vh"
className = "iframe"
display="initial" />
</div>
);
}
charlieftl's idea worked:
One suggestion would be pass all that to a component you render off screen and use a ref or ReactDOM.findDOMNode to access the outer element and then get it's outerHTML to write to iframe
I am trying to insert comments inside word document using insertOoxml method. The comment gets inserted successfully.
I want to delete this manually-inserted comment based on one of the user's actions. For example, when they switch from one feature of my add-in to another. I am trying to delete the comment parts from the Ooxml string using regex match and replace for this to work.
Word.run(async(context) => {
let body = context.document.body
let bodyOOXML = body.getOoxml()
await context.sync()
let bodyOOXMLText = bodyOOXML.value
bodyOOXMLText = bodyOOXMLText.replace(/<relationship(.*?)target="comments.xml(.*?)comments">/g, '')
bodyOOXMLText = bodyOOXMLText.replace(/<w:commentRangeStart(.*?)w:commentRangeEnd(.*?)\/>/g, '')
bodyOOXMLText = bodyOOXMLText.replace(/<w:comments(.*?)w:comments>/g, '')
bodyOOXMLText = bodyOOXMLText.replace(/<pkg:part(.*?)comments\+xml(.*?)word\/comments\.xml">(.*?)<\/pkg:part>/g, '')
body.insertOoxml(bodyOOXMLText, Word.InsertLocation.replace)
await context.sync()
})
It throws a GeneralException error. I think I'm corrupting the XML object somewhere, so just wanted to confirm
a. Is this a right approach/workaround to my problem?
b. What am I missing to replace here?
c. Is there any other sophisticated solution possible?
The regex method is not safe. The approach is still the same. Use XML parser and delete the relevant nodes from the XML DOM tree.
Code sample:
export function removeCommentsFromXML(xmlString){
let xmlText = ''
try{
// initialize DOM parser
let parser = new DOMParser()
let namespace = []
// parse XML string into XML DOM object
let xmlDoc = parser.parseFromString(xmlString, 'text/xml')
// get xml namespace prefix for 'pkg'
namespace['pkg'] = xmlDoc.documentElement.getAttribute('xmlns:pkg')
// get all 'pkg:part' nodes
let allChildrenNodes = xmlDoc.getElementsByTagNameNS(namespace['pkg'], 'part')
// delete comments.xml node in pkg:part
let currentChildNode = allChildrenNodes[0]
while (currentChildNode!==null && currentChildNode.getAttribute('pkg:name').match('comments.xml')===null) {
currentChildNode = currentChildNode.nextSibling
}
if(currentChildNode!==null) currentChildNode.parentNode.removeChild(currentChildNode)
// get document relationship package
currentChildNode = allChildrenNodes[0]
while (currentChildNode!==null && currentChildNode.getAttribute('pkg:name').match('word/_rels')===null) {
currentChildNode = currentChildNode.nextSibling
}
// get all relationships
let relationships = currentChildNode.getElementsByTagName('Relationship')
// delete comment relationship from relationships
let currentRelationship = relationships[0]
while (currentRelationship!==null && currentRelationship.getAttribute('Target').match('comments.xml')===null) {
currentRelationship = currentRelationship.nextSibling
}
if(currentRelationship!==null) currentRelationship.parentNode.removeChild(currentRelationship)
// get main document
currentChildNode = allChildrenNodes[0]
while (currentChildNode!==null && currentChildNode.getAttribute('pkg:name').match('/word/document.xml')===null) {
currentChildNode = currentChildNode.nextSibling
}
// get w namespace
namespace['w'] = currentChildNode.childNodes[0].childNodes[0].getAttribute('xmlns:w')
// get commentRangeStart nodes
let commentRangeStartNodes = currentChildNode.getElementsByTagNameNS(namespace['w'], 'commentRangeStart')
while(commentRangeStartNodes.length>0) {
commentRangeStartNodes[0].parentNode.removeChild(commentRangeStartNodes[0])
}
// get commentReference nodes
let commentReferenceNodes = currentChildNode.getElementsByTagNameNS(namespace['w'], 'commentReference')
while(commentReferenceNodes.length>0) {
commentReferenceNodes[0].parentNode.removeChild(commentReferenceNodes[0])
}
// get commentRangeEnd nodes
let commentRangeEndNodes = currentChildNode.getElementsByTagNameNS(namespace['w'], 'commentRangeEnd')
while(commentRangeEndNodes.length>0) {
commentRangeEndNodes[0].parentNode.removeChild(commentRangeEndNodes[0])
}
xmlText = new XMLSerializer().serializeToString(xmlDoc)
}
catch(err){
console.log(err)
}
return xmlText
}
the modified XML string can now be inserted using
body.insertOoxml(xmlText, Word.InsertLocation.replace)
I do not see what I am doing wrong:
var html = existingSelector.innerHTML;
var node = document.createTextNode(html);
existingSelector.parentNode.replaceChild(node, existingSelector);
existingSelector is the result of
selectedContents.querySelector("b");
Running the code correctly removes the "b" element, but does not insert the new node in its place. It simply deletes the entire node, without actually replacing it. As far as I can see, my syntax for the replaceChild() is correct though - ideas?
Edited Complete code:
this.bold = function() {
var selection = this.selection;
var selectedContents = selection.extractContents();
var existingSelector = selectedContents.querySelector("b");
if (existingSelector) {
var html = existingSelector.innerHTML;
var node = document.createTextNode(html);
console.log(node);
existingSelector.parentNode.replaceChild(node, existingSelector);
}
else {
var b = document.createElement("b");
b.appendChild(selectedContents);
selection.deleteContents();
selection.insertNode(b);
}
this.restoreSelection(selection);
}
I am trying to integrate meteor with another JS framework. I had things working fairly well prior to the latest Blaze upgrade (i.e. pre-version 0.8). In order to get this to work, I need to render a meteor template as an HTML string. Moreover, I need to be able to supply a data object to provide the values for the variables included in the template.
Pre 0.8, I could simply do the following:
var myTemplateName = 'someTemplateName';
var myTemplateVariableData = {myTemplateVariableData: {'xxx': 'some data}};
var myTemplateHTML = Template[myTemplateName].render(myTemplateVariableData);
Of course, that no longer works. However, I have to think there is some way to do this still even post-0.8. I have gotten fairly close with the following:
var myTemplateVariableData = {'xxx': 'some data};
var templateName = 'someTemplateName';
var myTemplateHTML = "";
var dr = new UI.DomRange; // domain range
var loadedTemplate = Template[templateName].extend(
{
data: function () {
return { myTemplateVariableData: myTemplateVariableData }
}
}
);
var renderedTemplate = loadedTemplate.render();
UI.materialize(renderedTemplate, dr, null, dr.component);
for (var member in dr.members) {
if (dr.members.hasOwnProperty(member)) {
var testHTML = dr.members[member].innerHTML;
if (testHTML) {
myTemplateHTML = myTemplateHTML + testHTML
} else {
myTemplateHTML = myTemplateHTML + dr.members[member].textContent
}
}
}
The problem with the result of this attempt is that if I try something like this:
{{#if myTemplateVariableData.xxx}}<span> {{myTemplateVariableData.xxx}}</span>{{/if}}
I will get the span showing up but no content other than the  . It seems as though when inside of an if block, it loses the context and can't see the myTemplateVariableData attribute on the 'this' object any longer.
I suspect there is an easier way to accomplish what I am trying to do here but I am out of ideas at present so I thought I'd post this here to see if anyone else had tried to do something similar.
My solution I think is a little more straight forward:
function html(contextObject, templateName) {
return Blaze.toHTML(Blaze.With(contextObject, function() { return Template[templateName]; }));
}
use:
template file
<template name="myTemplate">
<div id="{{myid}}"></div>
</template>
in some JS file
var myhtml = html({myid : 11}, "myTemplate") //<div id="1"></div>
To answer your question in the title, you could do it like this:
var templateName = 'myTemplate'
var context = {randomNumber: 527}
var div = document.createElement('div')
var component = UI.renderWithData(Template[templateName], context)
UI.insert(component, div)
var htmlString = div.innerHTML // <-- What you want.
But that's maybe not what you want?
I'm trying to replace lengthy XML tags with int values. Example '' as '<1>' so every tag with the name 'child' in the whole XML file will be replaces as '1'. I'm using libxmljs in NodeJS for this. So far my code is ;
var libxml = require('libxmljs');
var xml = '<?xml version="1.0" encoding="UTF-8"?>' +
'<root>' +
'<child foo="bar">' +
'<grandchild baz="fizbuzz">grandchild content</grandchild>' +
'</child>' +
'<child foo="bar1">' +
'<grandchild baz="fizbuzz">grandchild content 1</grandchild>' +
'</child>' +
'<sibling>with content!</sibling>' +
'</root>';
var xmlDoc = libxml.parseXml(xml);
var allxml = xmlDoc.root(); //store all nodes as allxml
var allNodes = xmlDoc.childNodes(); //all child nodes to array
rec(allxml);
function rec(anElement){
for (var j=0; j<allNodes.length;j++ )
{
var firstnode = allNodes[j].name(); //get tagname of the element
var findelem = xmlDoc.find(firstnode); //find similar elements with the tagname to array
var currChild = xmlDoc.child(j); //get current child element
var currnode = xmlDoc.childNodes(); // child nodes of current element to array
if (hasChild(currChild)) { // check whether this has child elements
rec(currChild.childNodes()); //if yes recall this function
}
else{ replaceCurrentTag(findelem, j);} // if no child nodes replace the name
}
}
function replaceCurrentTag(currelem, j){
for (var i=0;i<currelem.length;i++){
currelem[i].name(j.toString());
}
}
function hasChild(xmlElement){
var e = xmlElement.childNodes();
if (e.length > 0){ return true; }
else return false;
}
console.log(xmlDoc.toString());
But I'm getting this error when I run it in terminal.
/home/compaq/node_modules/libxmljs/lib/document.js:0
(function (exports, require, module, __filename, __dirname) { var bindings = r
^
RangeError: Maximum call stack size exceeded
What is that I'm doing wrong in here.
Please help.
Thank you
Your rec function iterates over allNodes, rather than the some subset of the nodes (probably the children of anElement). Combined with recursing into rec again before calling replaceCurrentTag (which never gets called), your function continues to call rec until you fill the call stack.