adding to a child node
adding to a child node
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
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
You need a variable containing the node object with the BatchID:
Then you need list of all the nodes to which you want to add the batchID node as a child:
Your XML is not complete so you may have to tweak the above somewhat, but this is the principle.
Code: Select all
var batchID = yourXML.evalToNode("/CustomBookProject/BatchID");
Code: Select all
var bookNodes = yourXML.evalToNodes("CustomBookProject/CustomBooks/CustomBook");
for (var i=0; i<bookNodes.length; i++) {
bookNodes.at(i).appendChild(batchID);
}
Re: adding to a child node
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());
}
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
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.
Code: Select all
job.sendToSingle(job.getPath());
Re: adding to a child node
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());
}
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
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
Hi,
That works great.
I get the result: <BatchID>10</BatchID></CustomBook>
Is there anyway to wrap the </CustomBook> to the next line?
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
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.
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.
Re: adding to a child node
Hi freddyp,
I tried running this script again this year and the script fails. The only thing that has changed is I've upgraded Switch recently.
Can you check it still works.
UPDATE: It works with a single CustomBook but not multiples
Thanks
Andrews
I tried running this script again this year and the script fails. The only thing that has changed is I've upgraded Switch recently.
Can you check it still works.
UPDATE: It works with a single CustomBook but not multiples
Thanks
Andrews
Re: adding to a child node
Anybody able to work out why it won't work with multiple nodes in the newer version of Switch?
the problem line appears to be:
bookNodes.at(i).appendChild(batchIDElement);
Only working as singles
TIA
the problem line appears to be:
bookNodes.at(i).appendChild(batchIDElement);
Only working as singles
TIA
Re: adding to a child node
It looks like creating a node and adding it multiple times causes the issue. Recreating the node each time solves it.
Can you try this code?
Can you try this code?
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);
for (var i=0; i<bookNodes.length; i++) {
var batchIDElement = theXML.createElement("BatchID");
batchIDElement.appendChild(batchIDText);
bookNodes.at(i).appendChild(batchIDElement);
}
// save the XML document
theXML.save(job.getPath());
job.sendToSingle(job.getPath());
}
Re: adding to a child node
Thanks.
That worked. Strange it didn't work by adding it multiple time.
That worked. Strange it didn't work by adding it multiple time.