Page 1 of 1
adding to a child node
Posted: Fri Dec 16, 2016 12:34 pm
by abonsey
Hi All,
I have some data supplied (see below) that has data at the parent node
CustomBook that I want to add to the child node
CustomBooks
I'd like to add the
BatchID data to each
CustomBooks node before saving.
The reason I do this is that the XML is then split later in the process using Saxon and then processed with Smartstream and I'll need the BatchID in Indesign.
Whilst I can create and add at the root level I've never been able to add it successfully at the child level.
Here's my test data
<?xml version="1.0"?>
<CustomBookProject>
<BatchID>10</BatchID>
<SourceFileName>FileA.xlsx</SourceFileName>
<CreationDateTime>2016-12-13T08:15:53.2168189+00:00</CreationDateTime>
<ProjectID>TestJob</ProjectID>
<JobCode>123456</JobCode>
<CustomBooks>
<CustomBook>
<ID>10256</ID>
<Index>1</Index>
<ID>17002314</MMU_ID>
<STATUS>EU</STUD_STATUS>
<Name_First>Andrew</Name_First>
<Name_Last>Smith</Name_Last>
<ShipmentAddress>
</ShipmentAddress>
<Pages>
</Pages>
</CustomBook>
<CustomBook>
<ID>10257</ID>
<Index>2</Index>
Thanks for any help. Hopefully I can get this cracked before the weekend festivities begin

Re: adding to a child node
Posted: Fri Dec 16, 2016 3:13 pm
by freddyp
You need a variable containing the node object with the BatchID:
Code: Select all
var batchID = yourXML.evalToNode("/CustomBookProject/BatchID");
Then you need list of all the nodes to which you want to add the batchID node as a child:
Code: Select all
var bookNodes = yourXML.evalToNodes("CustomBookProject/CustomBooks/CustomBook");
for (var i=0; i<bookNodes.length; i++) {
bookNodes.at(i).appendChild(batchID);
}
Your XML is not complete so you may have to tweak the above somewhat, but this is the principle.
Re: adding to a child node
Posted: Fri Dec 16, 2016 3:50 pm
by abonsey
Hi,
Thanks for the quick response.
The XML has multiple CustomBook nodes before closing off. Nothing else.
I used the following but nothing appears to happen within the flow. The test flow is simple... an input folder, an XML pickup before the script is run, followed by an output folder.
The Xml just sits at the input folder before the script.
Here's my script. Any thought? This is all a bit new to me.
// Is invoked each time a new job arrives in one of the input folders for the flow element.
// The newly arrived job is passed as the second parameter.
function jobArrived( s : Switch, job : Job )
{
//Get incoming XML file as a new XML document
var theXML = new Document(job.getPath());
//Extract the BatchID node from XML
var batchID = theXML.evalToNode("/CustomBookProject/BatchID");
//Select all CustomBook nodes and append to them
var bookNodes = theXML.evalToNodes("CustomBookProject/CustomBooks/CustomBook");
for (var i=0; i<bookNodes.length; i++) {
bookNodes.at(i).appendChild(batchID);
}
// save the XML document
theXML.save(job.getPath());
}
Re: adding to a child node
Posted: Fri Dec 16, 2016 4:25 pm
by freddyp
You are not sending the job to an output. Add:
And make sure that the script is set to have only 1 output. That is in the properties of the script in Switch Scripter.
Re: adding to a child node
Posted: Fri Dec 16, 2016 4:51 pm
by abonsey
Hi There,
Thanks for that! but it doesn't add the BatchID
Here's the sample xml with just one
CustomBook to be updated:
<?xml version="1.0" encoding="UTF-8"?>
<CustomBookProject>
<BatchID>10</BatchID>
<SourceFileName>File.xlsx</SourceFileName>
<CreationDateTime>2016-12-13T08:15:53.2168189+00:00</CreationDateTime>
<ProjectID>Test</ProjectID>
<JobCode>123456</JobCode>
<CustomBooks>
<CustomBook>
<ID>010256</ID>
<Index>1</Index>
<Name_First>Andrew</Name_First>
<Name_Last>Smith</Name_Last>
<ShipmentAddress>
<Room_No/>
<Address_1></Address_1>
<Address_2></Address_2>
<Address_3></Address_3>
<Address_4></Address_4>
<Address_5></Address_5>
<PostCode/>
</ShipmentAddress>
<Pages>
<Page name="D" index="2"/>
<Page name="D" index="3"/>
<Page name="D" index="4"/>
<Page name="D" index="5"/>
<Page name="D" index="6"/>
<Page name="D" index="7"/>
<Page name="B" index="8"/>
<Page name="A" index="10"/>
<Page name="A" index="15"/>
</Pages>
</CustomBook>
</CustomBooks>
</CustomBookProject>
And here's the script so far:function jobArrived( s : Switch, job : Job )
function jobArrived( s : Switch, job : Job )
{
//Get incoming XML file as a new XML document
var theXML = new Document(job.getPath());
//Extract the BatchID node from XML
var batchID = theXML.evalToNode("/CustomBookProject/BatchID");
//Select all CustomBook nodes and append to them
var bookNodes = theXML.evalToNodes("CustomBookProject/CustomBooks/CustomBook");
for (var i=0; i<bookNodes.length; i++) {
bookNodes.at(i).appendChild(batchID);
}
// save the XML document
theXML.save(job.getPath());
job.sendToSingle(job.getPath());
}
Re: adding to a child node
Posted: Sun Dec 18, 2016 8:29 pm
by freddyp
I noticed something strange that I will have to forward to engineering, but here is something that works. Instead of getting the node and adding it as a child, this code gets the value, creates a new node and adds that as a child.
Code: Select all
function jobArrived( s : Switch, job : Job )
{
//Get incoming XML file as a new XML document
var theXML = new Document(job.getPath());
//Extract the BatchID node from XML
var batchID = theXML.evalToString("/CustomBookProject/BatchID");
//Select all CustomBook nodes and append to them
var bookNodes = theXML.evalToNodes("/CustomBookProject/CustomBooks/CustomBook");
var batchIDText = theXML.createText(batchID);
var batchIDElement = theXML.createElement("BatchID");
batchIDElement.appendChild(batchIDText);
for (var i=0; i<bookNodes.length; i++) {
bookNodes.at(i).appendChild(batchIDElement);
}
// save the XML document
theXML.save(job.getPath());
job.sendToSingle(job.getPath());
}
Re: adding to a child node
Posted: Tue Dec 20, 2016 3:37 pm
by abonsey
Hi,
That works great.
I get the result: <BatchID>10</BatchID></CustomBook>
Is there anyway to wrap the </CustomBook> to the next line?
Re: adding to a child node
Posted: Tue Dec 20, 2016 3:44 pm
by freddyp
That is not necessary. XML files do not have to be nicely formatted to be processed correctly.
Any XML editor will satisfy your aesthetic expectations, either automatically (open the XML with a browser for example) or by clicking on a button/menu item that formats the XML stream.