44 #include <xercesc/util/PlatformUtils.hpp>
45 #include <xercesc/dom/DOMNamedNodeMap.hpp>
63 using namespace xercesc;
65 #define X(str) XString(str).unicode_str()
66 #define S(str) str.c_str()
78 void constructDocument(DOMElement* el);
79 void outputStream(DOMElement* thisEl, DOMElement* modelEl,
87 <<
" xml-hddm [-o <filename>] -t <template> [input file]\n\n"
89 <<
" -t <template> read template from <template>\n"
90 <<
" -o <filename> write to hddm file <filename>"
95 int main(
int argC,
char* argV[])
103 XMLPlatformUtils::Initialize();
105 catch (
const XMLException* toCatch)
108 <<
"hddm-xml: Error during initialization! :\n"
109 << toCatch->getMessage() << std::endl;
114 for (argInd = 1; argInd < argC; argInd++)
116 if (argV[argInd][0] !=
'-')
120 else if (strcmp(argV[argInd],
"-t") == 0)
122 templFilename = argV[++argInd];
124 else if (strcmp(argV[argInd],
"-o") == 0)
126 outFilename = argV[++argInd];
135 if (templFilename.size() == 0)
142 if (outFilename.size())
144 XString fname(outFilename +
".hddm");
145 builder.
ofs =
new std::ofstream(fname.c_str());
149 builder.
ofs = &std::cout;
152 #if defined OLD_STYLE_XERCES_PARSER
160 <<
"xml-hddm : Error parsing template HDDM document, "
161 <<
"cannot continue" << std::endl;
165 DOMElement* rootEl = document->getDocumentElement();
166 XString rootS(rootEl->getTagName());
170 <<
"xml-hddm error: root element of input document is "
171 <<
"\"" <<
S(rootS) <<
"\", expected \"HDDM\""
181 ifs =
new std::ifstream(0);
183 else if (argInd == argC - 1)
185 xmlFile =
XString(argV[argInd]);
186 ifs =
new std::ifstream(xmlFile.c_str());
194 if (! ifs->is_open())
197 <<
"xml-hddm: Error opening input stream "
198 << xmlFile << std::endl;
205 if (std::getline(*ifs,line))
207 if (line.substr(0,5) !=
"<?xml")
210 <<
"xml-hddm: Error reading input stream "
211 << xmlFile << std::endl;
213 <<
"Input file does not appear to be an xml document!"
221 <<
"xml-hddm: Error reading from input stream "
222 << xmlFile << std::endl;
226 if (std::getline(*ifs,line) && line.substr(0,5) !=
"<HDDM")
229 <<
"xml-hddm: Input document tag is not HDDM!"
236 std::stringstream tmpFileStr;
237 tmpFileStr <<
"tmp" << getpid();
238 while (getline(*ifs,line))
240 if (line.size() > 500000)
243 <<
"xml-hddm: line too long in input document" << std::endl;
249 std::ofstream ofs(tmpFileStr.str().c_str());
253 <<
"xml-hddm: Error opening temp file "
254 << tmpFileStr.str() << std::endl;
257 ofs << xmlHeader << std::endl;
258 ofs << docHeader << std::endl;
262 XString::size_type start = text.find_first_of(
"<");
263 if (start == XString::npos)
267 else if (text.substr(start,2) ==
"</")
271 XString::size_type end = text.find_first_of(
'>');
272 while (end == XString::npos)
274 if (line.size() > 400000)
277 <<
"xml-hddm: tag too long in input document" << std::endl;
282 std::getline(*ifs,line);
285 end = text.find_first_of(
'>');
287 if (text.substr(end-1,2) ==
"/>")
289 ofs << text.substr(0,end+1) << std::endl;
295 endTag =
"</" + text.substr(start+1,
296 text.find_first_of(
" \t",start)-start-1);
297 while (text.find(endTag) == XString::npos)
299 ofs << text << std::endl;
300 std::getline(*ifs,text);
302 ofs << text << std::endl;
304 ofs <<
"</HDDM>" << std::endl;
307 #if defined OLD_STYLE_XERCES_PARSER
315 <<
"xml-hddm : Error parsing HDDM document, "
316 <<
"cannot continue" << std::endl;
320 unlink(tmpFileStr.str().c_str());
322 DOMElement* thisEl = document->getDocumentElement();
324 std::ostringstream ofsbuf;
327 int size = (int)ofsbuf.tellp();
328 ofx << ((size > 0)? size : 0);
331 *builder.
ofs << ofsbuf.str();
336 if (builder.
ofs != &std::cout) {
337 ((std::ofstream*)builder.
ofs)->close();
339 unlink(tmpFileStr.str().c_str());
340 XMLPlatformUtils::Terminate();
348 static int indent = 0;
349 for (
int n = 0; n < indent; n++)
354 XString tagS(el->getTagName());
356 DOMNamedNodeMap* attrList = el->getAttributes();
357 int attrListLength = attrList->getLength();
358 for (
int a = 0; a < attrListLength; a++)
360 DOMNode* node = attrList->item(a);
361 XString nameS(node->getNodeName());
362 XString valueS(node->getNodeValue());
363 *ofs <<
" " << nameS <<
"=\"" << valueS <<
"\"";
366 DOMNodeList* contList = el->getChildNodes();
367 int contListLength = contList->getLength();
368 if (contListLength > 0)
370 *ofs <<
">" << std::endl;
372 for (
int c = 0;
c < contListLength;
c++)
374 DOMNode* node = contList->item(
c);
375 if (node->getNodeType() == DOMNode::ELEMENT_NODE)
377 DOMElement* contEl = (DOMElement*) node;
378 constructDocument(contEl);
382 for (
int n = 0; n < indent; n++)
386 *ofs <<
"</" << tagS <<
">" << std::endl;
390 *ofs <<
" />" << std::endl;
399 XString modelS(modelEl->getTagName());
400 XString thisS(thisEl->getTagName());
402 DOMNamedNodeMap* modelAttrList = modelEl->getAttributes();
403 int modelAttrListLength = modelAttrList->getLength();
404 DOMNamedNodeMap* thisAttrList = thisEl->getAttributes();
405 int thisAttrListLength = thisAttrList->getLength();
406 XString minS(modelEl->getAttribute(
X(
"minOccurs")));
407 XString maxS(modelEl->getAttribute(
X(
"maxOccurs")));
408 int expectAttrCount = modelAttrList->getLength()
409 - (minS ==
""? 0 : 1)
410 - (maxS ==
""? 0 : 1);
411 if (thisAttrListLength != expectAttrCount)
414 <<
"xml-hddm: Inconsistency in input xml document" << std::endl
415 <<
"tag " <<
S(thisS) <<
" in input document with "
416 << thisAttrListLength <<
" attributes " << std::endl
417 <<
"matched to tag " <<
S(modelS) <<
" in hddm template "
418 <<
"with " << expectAttrCount <<
" attributes." << std::endl;
423 for (
int a = 0; a < modelAttrListLength; a++)
425 XString attrS(modelAttrList->item(a)->getNodeName());
426 XString typeS(modelAttrList->item(a)->getNodeValue());
427 XString valueS(thisEl->getAttribute(
X(attrS)));
428 if (attrS ==
"maxOccurs" || attrS ==
"minOccurs")
432 else if (valueS ==
"" and typeS !=
"string")
435 <<
"xml-hddm: Inconsistency in input xml document" << std::endl
436 <<
"tag " <<
S(thisS) <<
" in input document is missing "
437 <<
"attribute " <<
S(attrS) << std::endl;
440 std::stringstream valueStr(valueS);
453 else if (typeS ==
"float")
456 if (valueS ==
"nan") {
459 else if (valueS ==
"-nan") {
462 else if (valueS ==
"inf") {
465 else if (valueS ==
"-inf") {
473 else if (typeS ==
"double")
476 if (valueS ==
"nan") {
479 else if (valueS ==
"-nan") {
482 else if (valueS ==
"inf") {
485 else if (valueS ==
"-inf") {
493 else if (typeS ==
"boolean")
499 else if (typeS ==
"Particle_t")
502 for (val = 0; val < 99; val++)
511 else if (typeS ==
"string" || typeS ==
"anyURI")
521 DOMNodeList* thisList = thisEl->getChildNodes();
522 int thisListLength = thisList->getLength();
523 DOMNodeList* modelList = modelEl->getChildNodes();
524 int modelListLength = modelList->getLength();
525 for (
int m = 0; m < modelListLength; m++)
527 DOMNode* mode = modelList->item(m);
528 short type = mode->getNodeType();
529 if (type == DOMNode::ELEMENT_NODE)
531 DOMElement* model = (DOMElement*) mode;
532 XString modelS(model->getTagName());
539 XString repS(model->getAttribute(
X(
"maxOccurs")));
540 int rep = (repS ==
"unbounded")? INT_MAX :
544 std::stringstream ofsbuf;
546 for (
int i = 0; i < thisListLength; i++)
548 DOMNode* instance = thisList->item(i);
549 short type = instance->getNodeType();
550 if (type == DOMNode::ELEMENT_NODE)
552 DOMElement* instanceEl = (DOMElement*) instance;
553 XString nameS(instanceEl->getTagName());
556 outputStream(instanceEl,model,ofsbuf);
557 if (repCount++ && (rep == 1))
560 <<
"xml-hddm: Inconsistency in input xml document"
562 <<
"tag " <<
S(thisS) <<
" in input document contains"
563 <<
" multiple instances of tag " <<
S(nameS)
565 <<
"but it does not have a maxOccurs=\"*\" attribute "
566 <<
"in the template." << std::endl;
569 else if (repCount > rep) {
571 <<
"xml-hddm: Inconsistency in input xml document"
573 <<
"tag " <<
S(nameS) <<
" in the template has "
574 <<
"maxOccurs=" << rep << std::endl
575 <<
"but the input document contains more than "
576 << rep <<
" instances." << std::endl;
583 int size = (int)ofsbuf.tellp();
586 ofx << (int32_t)((size > 0)? size+
sizeof(
int) :
sizeof(int))
587 << (int32_t)repCount;
591 ofx << (int32_t)((size > 0)? size : 0);
C++ iostream like interface to read and write xdr streams.
void constructDocument(DOMElement *el)
xercesc::DOMDocument * buildDOMDocument(const XString &xmlFile, bool keep)
static char * ParticleType(Particle_t p)
xercesc::DOMDocument * parseInputDocument(const XString &xmlFile, bool keep)
void outputStream(DOMElement *thisEl, DOMElement *modelEl, std::ostream &ofs)
int explicit_repeat_count
int main(int argc, char *argv[])