Code_TYMPAN  4.4.0
Industrial site acoustic simulation
DOMSave.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 #include <iostream>
17 #include <fstream>
18 
19 #include <qfile.h>
20 
21 #include "DOMSave.h"
22 #include <boost/foreach.hpp>
23 #include "Tympan/core/logging.h"
24 
25 using namespace std;
26 
28 // DOMSave
29 // ---------------------------------------------------------------------------
30 // Local const data
31 //
32 // Note: This is the 'safe' way to do these strings. If you compiler supports
33 // L"" style strings, and portability is not a concern, you can use
34 // those types constants directly.
35 // ---------------------------------------------------------------------------
36 
37 int DOMSave::saveNodeToFile(DOM_Node& nodeToSave, const char* fileName)
38 {
39  QFile file(fileName);
40  QByteArray byte_array;
41  QXmlStreamWriter xmlStream(&byte_array);
42  QDomDocument docToSave;
43  QDomElement elementToSave;
44  QDomElement rootElement;
45  bool ret = false;
46 
47  // If the node to save is already a document node print
48  // it. Otherwise, create new document, import the node to save
49  // into it and print it.
50  if (nodeToSave.isDocument())
51  {
52  docToSave = nodeToSave.toDocument();
53  }
54  else
55  {
56  docToSave.importNode(nodeToSave, true);
57  }
58 
59  xmlStream.setAutoFormatting(true);
60  xmlStream.setAutoFormattingIndent(1);
61 
62  xmlStream.writeStartDocument("1.0", false);
63  xmlStream.writeDTD("<!DOCTYPE Tympan SYSTEM 'Tympan.dtd'>");
64 
65  // Get root node of the document
66  rootElement = docToSave.documentElement();
67 
68  ret = writeElementToStream(rootElement, xmlStream);
69 
70  xmlStream.writeEndDocument();
71 
72  // If writing to QXmlStreamWriter succeeds then open file to replace its content
73  // Otherwise do not open file in order to preserve it
74  if (ret)
75  {
76  if (!file.open(QIODevice::WriteOnly))
77  {
78  return 3;
79  }
80  file.write(byte_array);
81  file.flush();
82  file.close();
83  return 0;
84  }
85  else
86  {
87  return -1;
88  }
89 }
90 
91 bool DOMSave::writeElementToStream(const QDomElement& pElement, QXmlStreamWriter& pStream)
92 {
93  bool ret = true;
94 
95  // Writes pElement to pStream
96  QString tagName = pElement.tagName();
97  pStream.writeStartElement(tagName);
98 
99  QVector<QString> attribute_names;
100  const QDomNamedNodeMap attributes = pElement.attributes();
101  for (int i = 0; i < attributes.length(); ++i)
102  {
103  attribute_names << attributes.item(i).toAttr().name();
104  }
105 
106  std::stable_sort(attribute_names.begin(), attribute_names.end());
107 
108  BOOST_FOREACH (QString attr_name, attribute_names)
109  {
110  const QDomAttr attr = attributes.namedItem(attr_name).toAttr();
111  QString attrName = attr.name();
112  QString attrValue = attr.value();
113  pStream.writeAttribute(attrName, attrValue);
114  }
115 
116  // Build node list from pElement in order to write recursively all QDomElement
117  const QDomNodeList nodeList = pElement.childNodes();
118  int nodecount = nodeList.length();
119 
120  for (int i = 0; i < nodecount; i++)
121  {
122  QDomNode nodeTosave = nodeList.item(i);
123  if (nodeTosave.isElement())
124  {
125  QDomElement elementToSave = nodeTosave.toElement();
126  ret = ret && writeElementToStream(elementToSave, pStream);
127  }
128  else if (nodeTosave.nodeType() == QDomNode::TextNode)
129  {
130  QDomText textToWrite = nodeTosave.toText();
131  pStream.writeCharacters(textToWrite.data());
132  }
133  else
134  {
135  OMessageManager::get()->info("Echec de la sauvegarde du noeud QDomNode %s de type %d",
136  nodeTosave.nodeName(), nodeTosave.nodeType());
137  ret = false;
138  }
139  }
140  pStream.writeEndElement();
141  return ret;
142 }
143 
145 {
146  QString outputString;
147  QTextStream textSream(&outputString);
148 
149  // XXX Encoding of project files is hardcoded here to be Latin-1
150  // TODO The handling of the encodings within XML, for file names and for the GUI is to be cleaned.
151  textSream << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>\n";
152 
153  // Is the node to save is already a document node print
154  // it. Otherwise, create new document, import the node to save
155  // into it and print it.
156  if (nodeToSave.isDocument())
157  {
158  textSream << nodeToSave.toDocument().toString();
159  }
160  else
161  {
162  QDomDocument doc;
163  doc.importNode(nodeToSave, true);
164  textSream << doc.toString();
165  }
166  return outputString;
167 }
QDomNode DOM_Node
Definition: QT2DOM.h:32
static QString saveNodeToString(DOM_Node &nodeToSave)
Methode pour la sauvegarde d'un noeud DOM dans une string XML.
Definition: DOMSave.cpp:144
static bool writeElementToStream(const QDomElement &pElement, QXmlStreamWriter &pStream)
Methode qui ecrit recursivement les noeuds d'un document xml dans un flux de type QXmlStreamWriter.
Definition: DOMSave.cpp:91
static int saveNodeToFile(DOM_Node &nodeToSave, const char *fileName)
La methode principale pour la sauvegarde d'un noeud DOM dans un fichier XML.
Definition: DOMSave.cpp:37
static OMessageManager * get()
Definition: logging.cpp:108
virtual void info(const char *message,...)
Definition: logging.cpp:143