How to use xmlNodeToDocument output

Could someone please direct me to some documentation on how to use pub.xml:xmlNodeToDocument in the receiving service?

Both the Built-in Services Reference and the XMLServicesDevGuide neglect to show an example of how to use the output “document” parameter. I’m currently mapping it to a document reference that matches the “$xmldata” field being passed from the client (the client follows the code example in the XMLServicesDevGuide section called “Submitting and Receiving XML in $xmldata”). But when I log fields of the output document, the data is null (actually blank). No arrays are involved, and I’m not setting any of the optional input parameters.

So I’m basically wondering how to access the output of xmlNodeToDocument. There’s plenty of documentation on using queryXMlNode, so I’m getting ready to try that instead, but I thought I’d first see if there were any simple things I’m missing on xmlNodeToDocument.

Thanks for any help.

Basically use this code for parsing your xmldata.

How are you receiving your xml via http post with content-type=text/xml ??

XMLStringToDocument(map $xmldata to xmldata string gives output node object)
xmlNodeToDocument (node automatically maps to input and map document output to documentReference (This IDATA document should be same as your $xmldata structure that you are receiving from external source) also set inputs makeArrays=false, documentTypeName(fully qualified document Name folder.subfolder:documentName).Now you can successfully parse your xml document.

PS:If xml posted via http then you have node object in the pipeline,and you can remove XMLStringToDocument service from the above step.

For testing debug the flow with step (F7 key)in the developer,you should see document in the pipeline thats comes out of node to document service.

Let us know if you have any questions.

HTH,
RMG

Strictly speaking, the XML is already parsed and is basically in a tree representation within the node object. xmlNodeToDocument converts this object to an IS document which may conform to an IS document type definition. This IS document is what you manipulate to work with data of interest. You can map fields from this document to another document. You can pass the fields to services. The output document is the thing you want to work with. queryXmlNode is useful in some situations but it really shouldn’t be used as the primary mechanism from which to get data from the document.

Take a look in the WmSamples package at the sample.complexMapping.standard.messageBuilder:buildPurchaseOrder service for an example of how the document is used for mapping. Use Test | Step to step through sample.complexMapping.standard.test:runComplexMapping to see how it all works and from there how you can code your own services.

I’m in town next week if you want to do lunch and go over some basics if you’d like. Good to see you on the forums!

Lunch sounds good. Any day but Monday (I’m working 4x10s now).

Thanks for those samples; it would have taken a while for me to have found them. It looks like I’m handling the output document correctly on the server side according to that sample. So the problem must be on the client side, which btw is running outside of webMethods, and I don’t know how to step it through in webMethods since the service is invoked from outside (is there a way to do that?), so I’m relying on logging debug info.

Today I created a test client flow to create the node so I can step it through within webMethods. I stepped it through and everything worked fine (I can see the output document data in the pipeline), which confirms my problem is on the client side. I’m following the client example found in the XMLServicesDevGuide (page 10 of the 6.1 version, or page 12 of the 6.5 version), which is different that the sample you mentioned (because it’s running outside webMethods). Here’s a code snippet:

[highlight=java]
// this defaults to binary format (RPC_BIN), but I’ve also tried
// RPC_IDAT and RPC_XML without success.
Context c = new Context();
c.setSecure(false); // use HTTP, not HTTPS
IData inputs = IDataFactory.create();
IDataCursor inputsCursor = inputs.getCursor();

// create the XML document
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\"?>");
sb.append("");
sb.append("");
sb.append("");
sb.append(getCostCenter());
sb.append("");
sb.append("");
sb.append(getDCE());
sb.append("");
sb.append("");
sb.append(getWorkOrder());
sb.append("");
sb.append("");
sb.append(getTask());
sb.append("");
sb.append("");
sb.append(getABM());
sb.append("");
sb.append("");
sb.append(getFERC());
sb.append("");
sb.append("");
sb.append(getAccountType());
sb.append("");
sb.append("");
sb.append(getDescriptionForHost());
sb.append("");
sb.append("");
sb.append("");
sb.append(getValidate());
sb.append("");
sb.append("");
sb.append(getEmployeeID());
sb.append("");
sb.append("");

// Assign XML document to String variable
String xmldata = sb.toString();

// Put XML document into $xmldata in IData object
inputsCursor.insertAfter("$xmldata", xmldata);

// Submit request to server
c.connect(“localhost:5555”, “rws5997”, “rws5997”);
IData outputs = c.invoke(“glAccountTable.apps”,“addGLAccountKeyXmlWrapper”, inputs);
c.disconnect();
[/highlight]
This is pretty much what the example shows in the XML Services Dev guide, except for how the XML is built.

I’m attaching a .gif file to show what the document looks like in Developer. Per your suggestion, I won’t pursue the queryXmlNode. I’m sure I’m missing something simple.

Thanks for your help!
doc.gif

Thanks for your reply. Since I got two replies before I could respond to one, I put my response to reamon’s reply. It looks like my problem is somewhere in my client code…I’m still looking.

The return of the c.invoke call is an IData object. You can retrieve data elements from that using the IS Java API. Look at the methods in the IDataUtil class. Add code similar to the following to get the outputs into vars you can use in the rest of your code:

[highlight=java]
IDataCursor idc = outputs.getCursor();
IData glAccountKey = IDataUtil.getIData(idc, “glAccountKey”);
boolean validate = false;
if(idc.first(“validate”))
validate = idc.getBoolean();
String employeeID = IDataUtil.getString(idc, “employeeID”);
idc.destroy();

// get the data out of the account key record
idc = glAccountKey.getCursor();
String costCenter = IDataUtil.getString(idc, “costCenter”);
String detailedCostElement = IDataUtil.getString(idc, "detailedCostElement ");
// … and so on
idc.destroy();[/highlight]
Perhaps the easiest thing to do is use Developer to generate the code for you. Select the service you want to call from your program. Select Tools | Generate Code… from the menu. Select “For calling this service from a client” and follow the rest of the wizard.

That said, it might be advisable to use the core Java classes to use HTTP post of the XML instead of using the IS API. That makes your code so that it will work with any web server instead of just IS and more people will understand that code instead of having to learn the IS Java API. There are samples of invoking services in this manner on the forums. Here’s one: http://wmusers.com/forum/showthread.php?t=4746&highlight=java+content-type

That’s a good idea, using an HTTP get or post. I’ve done that before and had success (though I haven’t tried it with an Xml document); I just wanted to try the webMethods protocol to get familiar with it.

In any case, I think I miscommunicated something. I have no problem retrieving the data out of the returned IData object in my client code. The problem I’m having is that when the client request gets to the server service, there’s no data to retrieve from the document that is output from xmlNodeToDocument. The reason I think my client code is the problem is because when I created a test client flow and created the node with xmlStringToNode, then the xmlNodeToDocument worked fine.

I didn’t realize Developer will generate the client code; I’ll try that next and compare it with what my current client code to see what is different, then I will let you know what I find.

Thanks for your help!

Well, I finally found the problem, and it was rather simple, so I feel a little foolish, but I wouldn’t have found it without your help. I also think it could have been avoided with a little extra explanation in the Built-in Services Reference. Here’s what I did:

I generated the client code, like you suggested, and added to it my code that built the Xml document, and it had exactly the same problem as I’ve had all along, so that narrowed the problem down to how I was creating the Xml document.

On a hunch , I removed the enclosing document tags ("" and “”) and wal…la, it worked (I wonder what worked so well that Walla Walla, Washington got its name). If you look at the IS document I attached to an earlier post, that tag was not part of the document. Instead, “inputDoc” was the name I had given to the document instance that I had mapped to the “document” output from xmlNodeToDocument.

Many thanks for your time. Email me what day you’d like to have lunch, and I’ll buy you lunch! And maybe our wives can join us and I’ll pay for all of us; in that case, Tuesday or Friday are best. But any day is okay with me except Monday. My email addr is still dsalisbury@…

Hi :slight_smile: I am currently having a problem using the xmlNodeToDocument. I tried quite several troubleshooting but still can’t figure out why this happens. Can you please help me out in case that you’re familiar with this case?

Scenario:
I was able to transform the node to a document based on the XML structure. But when passing it to another string, it don’t appear on the pipeline.