Check XML using xpath or script?

Post Reply
Dave23
Member
Posts: 41
Joined: Thu Oct 12, 2017 4:42 pm

Check XML using xpath or script?

Post by Dave23 »

Alright all,

I have a flow that currently takes some xml and then using xslt splits it up and then depending on a certain value in one of the attributes it moves down different routes.
I would like to evaluate the xml first however im not sure if i could use xpath or will i have to use a script, although i am very much a beginner when it comes to scripting.

The XML looks like this:

Code: Select all

<?xml version="1.0"?>
<Root>
  <IPN ID="11445" Name="Test">
    <CustomerProducts CustomerProductName="1-1" ProductCount="3">
      <Products ProductType="BOOK" ProductName="Cover" ProductNumber="1">
        <ProductComponents Languages="ENG" PageCount="2">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Inset" ProductNumber="2">
        <ProductComponents Languages="ENG" PageCount="200">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Wallet" ProductNumber="3">
        <ProductComponents Languages="ENG" PageCount="0">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
    </CustomerProducts>
    <CustomerProducts CustomerProductName="1-2" ProductCount="3">
      <Products ProductType="BOOK" ProductName="Cover" ProductNumber="1">
        <ProductComponents Languages="ENG" PageCount="2">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Inset" ProductNumber="2">
        <ProductComponents Languages="ENG" PageCount="0">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Wallet" ProductNumber="3">
        <ProductComponents Languages="ENG" PageCount="0">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
    </CustomerProducts>
    <CustomerProducts CustomerProductName="1-3" ProductCount="3">
      <Products ProductType="BOOK" ProductName="Cover" ProductNumber="1">
        <ProductComponents Languages="ENG" PageCount="2">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Inset" ProductNumber="2">
        <ProductComponents Languages="ENG" PageCount="150">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
      <Products ProductType="BOOK" ProductName="Wallet" ProductNumber="3">
        <ProductComponents Languages="ENG" PageCount="0">
          <ComponentSpecs SpecClass="" SpecType="" SpecValue="" />
        </ProductComponents>
      </Products>
    </CustomerProducts>
  </IPN>
</Root>
The amount of customerproducts can vary.

I need it to evaluate the XML by where PageCount="0" and ProductName is not ="Wallet". And if this is true i need it to take a different output route.

I hope this makes sense, any help appreciated.

Cheers
loicaigon
Advanced member
Posts: 378
Joined: Wed Jul 10, 2013 10:22 am

Re: Check XML using xpath or script?

Post by loicaigon »

Hi,

Switch Default variable evaluation is what you are looking for.

Loic
Dave23
Member
Posts: 41
Joined: Thu Oct 12, 2017 4:42 pm

Re: Check XML using xpath or script?

Post by Dave23 »

Hi loic. So would this be a script I need to create with these variables?
loicaigon
Advanced member
Posts: 378
Joined: Wed Jul 10, 2013 10:22 am

Re: Check XML using xpath or script?

Post by loicaigon »

Just use conditions on Metadata variables for sorting job.
cstevens
Member
Posts: 103
Joined: Tue Feb 12, 2013 8:42 pm

Re: Check XML using xpath or script?

Post by cstevens »

I'm not sure if you can use conditions with variables for XPaths that resolve to multiple nodes.

The XPath you're looking for is probably something like this:

/Root/IPN/CustomerProducts/Products[ProductComponents/@PageCount='0']/@ProductName

where you would compare the string result not equal to "Wallet", but in the sample you provided, that XPath matches 4 different nodes, and Switch doesn't seem to like XPaths that resolve to multiple nodes.

If you did it as a script you'd probably do something like this:

Code: Select all

function jobArrived( s : Switch, job : Job )
{
	var xmlDoc = new Document(job.getPath());
	//Find all the product nodes where PageCount="0"	
	var productNodes = xmlDoc.evalToNodes("/Root/IPN/CustomerProducts/Products[ProductComponents/@PageCount='0']", null);
	s.log(1, "Found " + productNodes.length + " products with PageCount=0.");

	var zeroPageNonWallet = false;
	//Parse through the product nodes to see if any of the ProductNames are not "Wallet"	
	for (var i=0; i<productNodes.length; i++){
		if(productNodes.at(i).evalToString("@ProductName", null) != "Wallet"){
			s.log(1, "Found a product with ProductName not equal to \"Wallet\", and PageCount equal to 0");
			zeroPageNonWallet = true;
			break;
		}
	}
	
	//Parse through connection list to find one with name "nonWalletZero"
	var connectionList = s.getOutConnections();
	var nonWalletZeroPageConnection = null;
	var otherConnection = null;
	for (var j=0; j<connectionList.length; j++){
		s.log(1, "Found an output connection with name: " + connectionList.at(j).getName());
		if(connectionList.at(j).getName() == "nonWalletZero"){
			nonWalletZeroPageConnection = connectionList.at(j);
		}
		else {
			otherConnection = connectionList.at(j);
		}
	}
	//If we don't have two valid output connections fail the job.
	if ((nonWalletZeroPageConnection == null) || (otherConnection == null)){
		job.fail("Failed to find 2 output Connections, one with name \"nonWalletZero\", can't route jobs to correct location!");
	}
	
	//Send job to the appropriate connection based on logic above
	if (zeroPageNonWallet){
		job.sendTo(nonWalletZeroPageConnection, job.getPath());
	}
	else {
		job.sendTo(otherConnection, job.getPath());
	}
}
Where the output of your script element had 2 connections, one with the name "nonWalletZero"

Maybe there's a way to do this with variable conditionals, but I'm not sure how.
Post Reply