XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Ethan SteinSubject: ddtekjava write to file only executed if return used?
Author: Ethan Stein
Date: 13 Dec 2011 11:32 PM
I have a ddtekjava function that takes in an element node and writes it to a file. It will then return a string indicating whether the write was successful or not. I have found that it only executes if I then use that string as a variable in my output. Is this expected behavior?

---------------------------

XQuery:

declare namespace xbef = 'ddtekjava:BuildErrorFile';

declare option ddtek:xml-streaming 'yes';
declare option ddtek:serialize "indent=yes, omit-xml-declaration=no";

(: Write error nodes to file :)
declare function xbef:writeXmlFile($outFile as xs:string, $rootNode as xs:string,
$elmToWrite as element(), $encoding as xs:string, $indent as xs:string, $append as xs:string) as xs:string external;

<SIMPLE_ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="VISA_DATA.xsd">
{for $acctRec at $index in (1 to 5)
let $nodesToWrite := <NODE_TO_WRITE>HELLO WORLD {$index}</NODE_TO_WRITE>
let $writeRecsToFile := xbef:writeXmlFile("C:\sampleFile.xml", "ROOT_NODE", $nodesToWrite, "UTF-8", "yes", "true")
return
<SOME_NODE>SAMPLE TEXT {$index}</SOME_NODE>
}
</SIMPLE_ROOT>
-----------------

Java Function:

/**
* Writes XML to file system
*
* @param outFile file to write to
* @param rootNode name of root node (used with new file)
* @param nodeToWrite elements to write to file
* @param encoding XML encoding type for output
* @param indent whether to indent or not (valid values are "yes" | "no")
* @param append flag indicating add to end of file or create new one (valid values are "true" | "false"
* @return Message indicating successful write or error
*/
public static String writeXmlFile(String outFile, String rootNode, Element nodeToWrite, String encoding, String indent, String append) {

FileOutputStream errorFOS = null;

try {

File sourceFile = new File(outFile);

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);

DocumentBuilder builder = factory.newDocumentBuilder();
Document errorDoc = null;

if (!sourceFile.exists() || !Boolean.parseBoolean(append)) {
errorDoc = builder.newDocument();
Element rootElm = errorDoc.createElement(rootNode);
rootElm.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
errorDoc.appendChild(rootElm);

} else
errorDoc = builder.parse(sourceFile);

Node elmNode = errorDoc.adoptNode(nodeToWrite);
errorDoc.getDocumentElement().appendChild(elmNode);

// Prepare the DOM document for writing
Source source = new DOMSource(errorDoc);

File errorFile = new File(outFile);

errorFOS = new FileOutputStream(errorFile);
Result result = new StreamResult(errorFOS);

// Write the DOM document to the file
TransformerFactory xFormerFactory = TransformerFactory.newInstance();
Transformer xformer = xFormerFactory.newTransformer();

xformer.setOutputProperty(OutputKeys.INDENT, indent);
xformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "5");
xformer.setOutputProperty(OutputKeys.ENCODING, encoding);
xformer.setOutputProperty(OutputKeys.STANDALONE, "no");

xformer.transform(source, result);

return ("Write to " + outFile + " successful.");

} catch (TransformerConfigurationException tce) {
tce.printStackTrace();
return tce.getMessage();
} catch (TransformerException te) {
te.printStackTrace();
return te.getMessage();
} catch (FileNotFoundException e) {
e.printStackTrace();
return e.getMessage();
} catch (ParserConfigurationException e) {
e.printStackTrace();
return e.getMessage();
} catch (SAXException e) {
e.printStackTrace();
return e.getMessage();
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
} finally {
try {
if (errorFOS != null)
errorFOS.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Postnext
Ivan PedruzziSubject: ddtekjava write to file only executed if return used?
Author: Ivan Pedruzzi
Date: 13 Dec 2011 11:52 PM

XQuery 1.0 is a side effect free language, therefore if an expression is not used, the implementation has freedom to optimize out then un-used code.

The way to get around it, is having the function to return an empty sequence, so it can be called as part of the return value.

ddtek:serialize-to-url should suffix your needs.

Hope this helps
Ivan Pedruzzi
Stylus Studio Team

Postnext
Ethan SteinSubject: ddtekjava write to file only executed if return used?
Author: Ethan Stein
Date: 14 Dec 2011 12:03 AM
Ah, I understand. I switched the function to return an empty sequence and then simply changed it to this:

(: Write error nodes to file :)
declare function xbef:writeXmlFile($outFile as xs:string, $rootNode as xs:string,
$elmToWrite as element(), $encoding as xs:string, $indent as xs:string, $append as xs:string) as empty-sequence() external;


let $writeRecsToFile := xbef:writeXmlFile("C:\sampleFile.xml", "ROOT_NODE", $nodesToWrite, "UTF-8", "yes", "true")
return
<SOME_NODE>SAMPLE TEXT {$index}{$writeRecsToFile}</SOME_NODE>

Now it works. Thanks!

Postnext
Ethan SteinSubject: ddtekjava write to file only executed if return used?
Author: Ethan Stein
Date: 14 Dec 2011 12:15 AM
I guess I'm not quite understanding what you're referring to by having a function to return an empty sequence. Can you give me an example?

Posttop
Ethan SteinSubject: ddtekjava write to file only executed if return used?
Author: Ethan Stein
Date: 14 Dec 2011 12:36 AM
Okay, I think I understand. I can use the return of ddtek:seralize-to-url(...) and return that as an empty-sequence() in the function. Then I simply include the result.

So I have your function from before:

declare function local:addNode($error as element()) as empty-sequence()
{
let $errLog := if(fn:doc-available($logURL)) then
doc($logURL)/Errors
else ()
let $newLog :=
<Errors
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ErrorNodes.xsd">
{
$errLog/*,
$error
}
</Errors>

return ddtek:serialize-to-url($newLog, $logURL,"indent=yes, omit-xml-declaration=no")
};

And I call it like so:

let $nodeAdded := local:addNode(<MESSAGE_WHITE_SPACE>{concat("The white space size (for VISA region 01B) for &quot;", $acctRecNum, ".xml&quot; could not be found. Please check the xDoc output.")}</MESSAGE_WHITE_SPACE>)
return ($nodeAdded,$n))

The trick was I was missing the () around the return values so it wasn't picking them up. Thanks!

 
Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.