rusle2XML.cc [tools/Rusle2SoilsXMLCreator/pg/rusle2_from_ssurgo_build_newbackup] Revision: Date:
#include <iostream>
#include <string>
#include <cstring>
#include <boost/lexical_cast.hpp>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include "rusle2_from_ssurgo.h"
using namespace std;
using boost::lexical_cast;
/**
* ConvertInput:
* @in: string in a given encoding
* @encoding: the encoding used
*
* Converts @in into UTF-8 for processing with libxml2 APIs
*
* Returns the converted UTF-8 string, or NULL in case of error.
*/
xmlChar *
ConvertInput(const char *in, const char *encoding)
{
xmlChar *out;
int ret;
int size;
int out_size;
int temp;
xmlCharEncodingHandlerPtr handler;
if (in == 0)
return 0;
handler = xmlFindCharEncodingHandler(encoding);
if (!handler) {
printf("ConvertInput: no encoding handler found for '%s'\n",
encoding ? encoding : "");
return 0;
}
size = (int) strlen(in) + 1;
out_size = size * 2 - 1;
out = (unsigned char *) xmlMalloc((size_t) out_size);
if (out != 0) {
temp = size - 1;
ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
if ((ret < 0) || (temp - size + 1)) {
if (ret < 0) {
printf("ConvertInput: conversion wasn't successful.\n");
} else {
printf
("ConvertInput: conversion wasn't successful. converted: %i octets.\n",
temp);
}
xmlFree(out);
out = 0;
} else {
out = (unsigned char *) xmlRealloc(out, out_size + 1);
out[out_size] = 0; /*null terminating out */
}
} else {
printf("ConvertInput: no mem\n");
}
return out;
}
/* AttrXML:
* @writer : libxml2 text writer
* @pszTag : The element tag for this attr type (ex: "Flt", "Bol",...)
* @pszRusle2Name : Name Element, this is expected in all cases.
* @value : Value element, this is expected in all cases.
* @pszDims : Uknown...number of dimensions? Only used in map unit elements...
* @pszUnit : Unit of value, not always present but usually is (when there are units!)
*
* Writes to xml writer object @writer an element tag defined by attributes and data passed in
* Something like below would be created
* <@pszTag>
* <Name>@pszRusle2Name</Name>
* <Data>@value</data>
* <dims>@pszDims</dims>
* <Unit>@pszUnit</Unit>
* </@pszTag>
*/
int
AttrXML (xmlTextWriterPtr writer, string pszTag, string pszRusle2Name, string value, string pszDims, string pszUnit )
{
/* Start pszTag */
int rc = xmlTextWriterStartElement(writer, BAD_CAST pszTag.c_str());
/* Name Element */
if( rc >= 0 )
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Name", ConvertInput(pszRusle2Name.c_str(), MY_ENCODING) );
/* Value Element */
if( rc >= 0 )
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Data", ConvertInput(value.c_str(), MY_ENCODING) );
/* Dims Element
* Not always present
*/
if( rc >= 0 && pszDims.length() > 0 )
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Dims", ConvertInput(pszDims.c_str(), MY_ENCODING) );
/* There was an RX_VARIANT_TEMPLATE item commented out right here */
/* Element was called "Var" and seemed to specify cumulative or not... */
/* Unit Element
* Not always present
*/
if( rc >= 0 && pszUnit.length() > 0 )
rc = xmlTextWriterWriteElement(writer, BAD_CAST "Unit", ConvertInput(pszUnit.c_str(), MY_ENCODING) );
/* End pszTag */
if( rc >= 0 )
rc = xmlTextWriterEndElement(writer);
return rc;
}
/*
* AttrXML:
* @writer : libxml2 text writer
* @pszTag : The element tag for this attr type (ex: "Flt", "Bol",...)
* @pszRusle2Name : Name Element, this is expected in all cases.
* @low : Low value element
* @rep : Representative value element
* @high : High value element
* @pszDims : Uknown...number of dimensions? Only used in map unit elements...
* @pszUnit : Unit of value, not always present but usually is (when there are units!)
*
* Create an XML element for an attribute and data
* This template includes the low, representative, and high values
* It evaluates to see if the rep value is valid or not
* If not it takes a simple average of high and low, then sends that value off to create the XML element and data
*
* Once value is determined to be the representative value or the average of high/low, we create the element by:
* AttrXML( @writer, @pszTag, @pszRusle2Name, @value, @pszDims, @pszUnit)
*/
int
AttrXML (xmlTextWriterPtr writer, string pszTag, string pszRusle2Name, string low, string rep, string high, string pszDims, string pszUnit )
{
/* Use representitive value if possible */
/* If rep value is null, try to do a simple average */
string value = rep;
if( rep.length() <= 0 )
value = lexical_cast<string>((atof(low.c_str()) + atof(high.c_str())) / 2);
/* If nothing still...throw a NaN */
if ( value == "" )
value = "NaN";
return AttrXML( writer, pszTag, pszRusle2Name, value, pszDims, pszUnit );
}