Page 1 of 1

Add Attribute to XML, with a twist.

Posted: Fri Sep 13, 2019 7:57 pm
by actionHero
Hello,
I have an XML that I need to add an attribute to based on another XML in a folder.

Original XML (this may have one ISBN to look up or 100).
<details>
<detail ID="1" isbn="987654321000" title="" qty="10" />
<detail ID="2" isbn="987654321001" title="" qty="11" />
<detail ID="3" isbn="987654321002" title="" qty="12" />
</details>

I have a folder of XMl's, each named an ISBN. Inside the xml is a node with a job number. I need to be able to take the ISBN in the original XML, search the folder, find the XML with same ISBN name, grab the node for jobnumber, add attribute to Original XML. I own XML Magic App, not sure if this is something that can be done with that?

Final XML

<details>
<detail ID="1" isbn="987654321000" title="" qty="10" jobnumber="123456" />
<detail ID="2" isbn="987654321001" title="" qty="11" jobnumber="123457" />
<detail ID="3" isbn="987654321002" title="" qty="12" jobnumber="123458" />
</details>

Re: Add Attribute to XML, with a twist.

Posted: Fri Sep 13, 2019 9:46 pm
by cstevens
Edit. I misread your post originally, this is updated to reflect more what you wanted.

Something like this maybe? I don't know what the structure of the XML file you're searching for the job number is, or which if the xml files is triggering the script. I'm assuming (probably incorrectly) that the file with the jobnumber is coming into the script.

Code: Select all

	//open the original XML as an XML DOM	
	var origXML = new Document(origXMLPath);
	
	//get the folder and list of XML files contained in it (assuming this folder is coming into this script as a job input)
	var inFolder = new Dir(job.getPath());
	var fileList = inFolder.entryList("*.xml", Dir.Files, Dir.Name);
	
	//get the list of detail nodes from original XML file
	var detailList = origXML.evalToNodes("//details/detail", null);
	var isbn = "";
	var xmlFileName= "";
	var jobNumber = "";
	//for each node get the isbn number then search the folder of XML files for a node that matches that ISBN
	for (var i=0; i<detailList.length; i++){
		detailList.at(i).getAttribute("isbn");
		s.log(1, "Checking input XML files for matching isbn number of: " + isbn);
		for(var j=0; j<fileList.length; j++){
			if(fileList[i].indexOf(isbn) != -1){
				xmlFileName = fileList[i];
				break
			}
			//open one of the folder XML files as DOM
			folderXML = new Document(inFolder.path + "\\" + xmlFileName);
			jobNumber = folderXML.evalToString("//XPath/to/jobnumber", null);
			if(jobNumber != ""){
				s.log(1, "Found matching detail node with jobnumber value of: " + jobNumber);
				//add the jobnumber attribute to the original XML file
				detailList.at(i).addAttribute("jobnumber", null, jobNumber);
				jobNumber = "";
			}
		}
	}
	//save changes to original XML file
	origXML.save(orgXMLPath);

Re: Add Attribute to XML, with a twist.

Posted: Fri Sep 13, 2019 10:38 pm
by actionHero
Thanks for the response. The folder of XML's with job numbers will be a repository. I wont know what XML's exist, just need to search for the ISBN via the tag in original XML. The original XML will trigger the search of the repository.

Thanks,
Adam

Re: Add Attribute to XML, with a twist.

Posted: Fri Sep 13, 2019 10:58 pm
by cstevens
So is the original XML file coming into the script? This should still be valid, you just need to change the paths to the original xml file (job.getPath()), the xml folder repository location, and the XPath where the jobnumber is located within the xml file(s) in the repository.

Is the ISBN number in the xml file name inside the repository, or do you have to actually open each XML file and look for the isbn number inside the file?

Re: Add Attribute to XML, with a twist.

Posted: Sat Sep 14, 2019 12:56 pm
by actionHero
Hello,
Yes the Original XML comes in to the script, it is an Order xml. Orders are received and they need to grab book spec data from our MIS... however I can only search my MIS by job number to grab the book spec data. I'm creating the repository of XML's that are named the ISBN, then inside the XML will be the MIS job number. The order XML comes in, needs to find the ISBN XML in repository, then open it and grab the MIS job number, and add that to the Order attribute.

Thanks!

Re: Add Attribute to XML, with a twist.

Posted: Mon Sep 16, 2019 9:07 pm
by actionHero
I'm getting an error saying, "Error in line 30 of script : TypeError. 'getAttribute' undefined or not a function". Must be a different way I need to write, detailList.at(i).getAttribute("isbn");

Re: Add Attribute to XML, with a twist.

Posted: Tue Sep 17, 2019 11:52 pm
by mkayyyy
actionHero wrote: Mon Sep 16, 2019 9:07 pm I'm getting an error saying, "Error in line 30 of script : TypeError. 'getAttribute' undefined or not a function". Must be a different way I need to write, detailList.at(i).getAttribute("isbn");
The function needs to be getAttributeValue. Also the value returned from that function needs to be assigned to the variable isbn:

Code: Select all

isbn = detailList.at(i).getAttributeValue("isbn", null);

Re: Add Attribute to XML, with a twist.

Posted: Mon Sep 23, 2019 6:34 pm
by actionHero
Thank you for the replay. I have it working in a perfect scenario but not every scenario.

First I need it to fail to traffic light connector if an ISBN can't be found. An incoming XML could have many ISBN's in the order. Currently if all the ISBN's exist in the folder, it works fine. But if one of the line item ISBN's doesn't exist, the scripts places the last known job number in the field as opposed to failing to traffic light connector. I realize i'm not telling it to fail at the moment but that's why i'm asking... I'm not totally sure how to get to fail the whole file even even one of the ISBN's cant be found.

Code: Select all

// 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 )
{
//open the original XML as an XML DOM
var doc = job.getPath();
var origXML = new Document(doc);
//get the folder and list of XML files contained in it input)
var inFolder = new Dir("C:/Users/Enfocus.KY-SW1/Documents/FM_Parts");
var fileList = inFolder.entryList("*.xml", Dir.Files, Dir.Name);
s.log(1,fileList);

//get the list of detail nodes from original XML file
var detailList = origXML.evalToNodes("//metadata/orders/order/details/detail", null);
var isbn = "";
var xmlFileName= "";
var jobNumber = "";
s.log(2, "Made it here - 1");
var test= detailList.length;
s.log(2, test);

  //for each node get the isbn number then search the folder of XML files for a node that matches that ISBN
for (var i=0; i<detailList.length; i++){
var thenode = detailList.getItem(i);
var id = thenode.getAttributeValue("isbn",null);
s.log(3, id);
s.log(1, "Checking input XML files for matching isbn number of: " + id);

for(var j=0; j<fileList.length; j++)
	if(fileList[j].indexOf(id) != -1){
       xmlFileName = fileList[j]
					 break;
   } 


s.log(2, "Made it here - 2");
//open one of the folder XML files as DOM

folderXML = new Document(inFolder.path + "/" + xmlFileName);

jobNumber = folderXML.evalToString("//csv/field[1]", null);
s.log(2, jobNumber);
if(jobNumber != ""){
s.log(2, "Found matching detail node with jobnumber value of: " + jobNumber);
//add the jobnumber attribute to the original XML file
detailList.at(i).addAttribute("jobnumber", null, jobNumber);
jobNumber = "";}

}
//save changes to original XML file
origXML.save(job.getPath() );
job.sendToData(1, job.getPath() );
}

Re: Add Attribute to XML, with a twist.

Posted: Wed Sep 25, 2019 10:48 pm
by mkayyyy
To get the script to fail the whole file if one of the ISBNs don't exist I went with this which seems to work:

Code: Select all

// 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 ) {
	//open the original XML as an XML DOM
	var doc = job.getPath();
	var origXML = new Document(doc);
	//get the folder and list of XML files contained in it input
	var inFolder = new Dir("C:/Users/Enfocus.KY-SW1/Documents/FM_Parts");
	
	//get the list of detail nodes from original XML file
	var detailList = origXML.evalToNodes("//detail", null);
	var allFilesExist = true;
	var allJobNames = true;
	
	for (var i = 0; i < detailList.length; i += 1) {
		var currentNode = detailList.getItem(i);
		var isbnAttr = currentNode.getAttributeValue("isbn", null);
		
		var isbnFile = inFolder.entryList(isbnAttr + ".xml", Dir.Files, Dir.Name);
		
		if (isbnFile.length !== 0) {
			folderXML = new Document(inFolder.path + "/" + isbnFile);
			
			jobNumber = folderXML.evalToString("//csv/field[2]", null);
			
			if (jobNumber !== "") {
				s.log(2, "Found matching detail node with jobnumber value of: " + jobNumber);
				//add the jobnumber attribute to the original XML file
				detailList.at(i).addAttribute("jobnumber", null, jobNumber);
			} else {
				allJobNames = false;
				break;
			}
		} else {
			allFilesExist = false;
			break;
		}
	}
	
	if (allFilesExist && allJobNames) {
		//save changes to original XML file
		origXML.save(job.getPath());
		job.sendToData(1, job.getPath());
	} else {
		//send to error connection
		job.log(3, "Missing isbn XML file/Missing jobnumber");
		job.sendToData(3, job.getPath());
	}
}
I ended up creating two variables allFilesExist and allJobNames and setting them both to true. Then whilst the for loop is running if the ISBN file doesn't exist then change that variable to false and break from the loop, same with the check that jobnumber (//csv/field[2]) isn't an empty string.

Then once the loop has finished check that both allFilesExist and allJobNames are true otherwise send to the error connection.

Re: Add Attribute to XML, with a twist.

Posted: Thu Sep 26, 2019 4:04 pm
by cstevens
Sorry, I must have accidentally unsubscribed to this thread. Sorry to leave you hanging like that. Looks like you got it working though.

Re: Add Attribute to XML, with a twist.

Posted: Thu Sep 26, 2019 7:49 pm
by actionHero
Thank you for all the help, it works just as expected now. This is very helpful!

Re: Add Attribute to XML, with a twist.

Posted: Thu Sep 26, 2019 7:49 pm
by actionHero
Thank you for all the help, it works just as expected now. This is very helpful!

Re: Add Attribute to XML, with a twist.

Posted: Thu Sep 26, 2019 10:55 pm
by mkayyyy
actionHero wrote: Thu Sep 26, 2019 7:49 pm Thank you for all the help, it works just as expected now. This is very helpful!
No problem! Glad I could help :)