You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
368 lines
10 KiB
368 lines
10 KiB
15 years ago
|
/***************************************************************************
|
||
|
* Copyright (C) 2001-2002 by Bernd Gehrmann *
|
||
|
* bernd@kdevelop.org *
|
||
|
* default support: Eray Ozkural (exa) *
|
||
|
* additions: John Firebaugh <jfirebaugh@kde.org> *
|
||
|
* Jakob Simon-Gaarde <jakob@simon-gaarde.dk> *
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "domutil.h"
|
||
|
|
||
|
#include <kdebug.h>
|
||
|
#include <qstringlist.h>
|
||
|
#include <qfile.h>
|
||
|
|
||
|
|
||
|
void DomUtil::makeEmpty( QDomElement& e )
|
||
|
{
|
||
|
while( !e.firstChild().isNull() )
|
||
|
e.removeChild( e.firstChild() );
|
||
|
}
|
||
|
|
||
|
QDomElement DomUtil::elementByPath(const QDomDocument &doc, const QString &path)
|
||
|
{
|
||
|
QStringList l = QStringList::split('/', path);
|
||
|
|
||
|
QDomElement el;
|
||
|
if(&doc) el = doc.documentElement();
|
||
|
QStringList::ConstIterator it;
|
||
|
for (it = l.begin(); it != l.end(); ++it) {
|
||
|
el = el.namedItem(*it).toElement();
|
||
|
}
|
||
|
|
||
|
return el;
|
||
|
}
|
||
|
|
||
|
|
||
|
QString DomUtil::readEntry(const QDomDocument &doc, const QString &path, const QString &defaultEntry)
|
||
|
{
|
||
|
QDomElement el = elementByPath(doc, path);
|
||
|
if (el.isNull())
|
||
|
return defaultEntry;
|
||
|
else
|
||
|
return el.firstChild().toText().data();
|
||
|
}
|
||
|
|
||
|
/// @todo consider whether it's okay to accept empty string == default value
|
||
|
/// if not use the below type
|
||
|
///typedef pair<bool,QString> EltInfo;
|
||
|
|
||
|
QString DomUtil::readEntryAux(const QDomDocument &doc, const QString &path)
|
||
|
{
|
||
|
QDomElement el = elementByPath(doc, path);
|
||
|
if (el.isNull())
|
||
|
return QString::null;
|
||
|
else
|
||
|
return el.firstChild().toText().data();
|
||
|
}
|
||
|
|
||
|
int DomUtil::readIntEntry(const QDomDocument &doc, const QString &path, int defaultEntry)
|
||
|
{
|
||
|
QString entry = readEntryAux(doc, path);
|
||
|
if (entry.isNull())
|
||
|
return defaultEntry;
|
||
|
else
|
||
|
return entry.toInt();
|
||
|
}
|
||
|
|
||
|
|
||
|
bool DomUtil::readBoolEntry(const QDomDocument &doc, const QString &path, bool defaultEntry)
|
||
|
{
|
||
|
QString entry = readEntryAux(doc, path);
|
||
|
if (entry.isNull())
|
||
|
return defaultEntry;
|
||
|
else
|
||
|
return entry == "TRUE" || entry == "true";
|
||
|
}
|
||
|
|
||
|
|
||
|
QStringList DomUtil::readListEntry(const QDomDocument &doc, const QString &path, const QString &tag)
|
||
|
{
|
||
|
QStringList list;
|
||
|
|
||
|
QDomElement el = elementByPath(doc, path);
|
||
|
QDomElement subEl = el.firstChild().toElement();
|
||
|
while (!subEl.isNull()) {
|
||
|
if (subEl.tagName() == tag)
|
||
|
list << subEl.firstChild().toText().data();
|
||
|
subEl = subEl.nextSibling().toElement();
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
|
||
|
DomUtil::PairList DomUtil::readPairListEntry(const QDomDocument &doc, const QString &path, const QString &tag,
|
||
|
const QString &firstAttr, const QString &secondAttr)
|
||
|
{
|
||
|
PairList list;
|
||
|
|
||
|
QDomElement el = elementByPath(doc, path);
|
||
|
QDomElement subEl = el.firstChild().toElement();
|
||
|
while (!subEl.isNull()) {
|
||
|
if (subEl.tagName() == tag) {
|
||
|
QString first = subEl.attribute(firstAttr);
|
||
|
QString second = subEl.attribute(secondAttr);
|
||
|
list << Pair(first, second);
|
||
|
}
|
||
|
subEl = subEl.nextSibling().toElement();
|
||
|
}
|
||
|
|
||
|
return list;
|
||
|
}
|
||
|
|
||
|
QMap<QString, QString> DomUtil::readMapEntry(const QDomDocument &doc, const QString& path)
|
||
|
{
|
||
|
QMap<QString, QString> map;
|
||
|
|
||
|
QDomElement el = elementByPath(doc, path);
|
||
|
QDomElement subEl = el.firstChild().toElement();
|
||
|
while (!subEl.isNull()) {
|
||
|
map[subEl.tagName()] = subEl.firstChild().toText().data();
|
||
|
subEl = subEl.nextSibling().toElement();
|
||
|
}
|
||
|
|
||
|
return map;
|
||
|
}
|
||
|
|
||
|
QDomElement DomUtil::namedChildElement( QDomElement& el, const QString& name )
|
||
|
{
|
||
|
QDomElement child = el.namedItem( name ).toElement();
|
||
|
if (child.isNull()) {
|
||
|
child = el.ownerDocument().createElement( name );
|
||
|
el.appendChild(child);
|
||
|
}
|
||
|
return child;
|
||
|
}
|
||
|
|
||
|
|
||
|
QDomElement DomUtil::createElementByPath(QDomDocument &doc, const QString &path)
|
||
|
{
|
||
|
QStringList l = QStringList::split('/', path);
|
||
|
|
||
|
QDomElement el;
|
||
|
if(&doc) el = doc.documentElement();
|
||
|
QStringList::ConstIterator it;
|
||
|
for (it = l.begin(); it != l.end(); ++it)
|
||
|
el = DomUtil::namedChildElement( el, *it );
|
||
|
|
||
|
while (!el.firstChild().isNull())
|
||
|
el.removeChild(el.firstChild());
|
||
|
|
||
|
return el;
|
||
|
}
|
||
|
|
||
|
|
||
|
void DomUtil::writeEntry(QDomDocument &doc, const QString &path, const QString &value)
|
||
|
{
|
||
|
QDomElement el = createElementByPath(doc, path);
|
||
|
el.appendChild(doc.createTextNode(value));
|
||
|
}
|
||
|
|
||
|
void DomUtil::writeMapEntry(QDomDocument &doc, const QString &path, const QMap<QString, QString> &map)
|
||
|
{
|
||
|
QString basePath( path + "/" );
|
||
|
QMap<QString,QString>::ConstIterator it;
|
||
|
for (it = map.begin(); it != map.end(); ++it)
|
||
|
{
|
||
|
kdDebug( 9010 ) << "writing " << basePath << ";" << it.key() << ";" << it.data() << endl;
|
||
|
if( ! it.key().isEmpty() )
|
||
|
writeEntry(doc, basePath + it.key(), it.data() );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DomUtil::writeIntEntry(QDomDocument &doc, const QString &path, int value)
|
||
|
{
|
||
|
writeEntry(doc, path, QString::number(value));
|
||
|
}
|
||
|
|
||
|
|
||
|
void DomUtil::writeBoolEntry(QDomDocument &doc, const QString &path, bool value)
|
||
|
{
|
||
|
writeEntry(doc, path, value? "true" : "false");
|
||
|
}
|
||
|
|
||
|
|
||
|
void DomUtil::writeListEntry(QDomDocument &doc, const QString &path, const QString &tag,
|
||
|
const QStringList &value)
|
||
|
{
|
||
|
QDomElement el = createElementByPath(doc, path);
|
||
|
|
||
|
QStringList::ConstIterator it;
|
||
|
for (it = value.begin(); it != value.end(); ++it) {
|
||
|
QDomElement subEl = doc.createElement(tag);
|
||
|
subEl.appendChild(doc.createTextNode(*it));
|
||
|
el.appendChild(subEl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void DomUtil::writePairListEntry(QDomDocument &doc, const QString &path, const QString &tag,
|
||
|
const QString &firstAttr, const QString &secondAttr,
|
||
|
const PairList &value)
|
||
|
{
|
||
|
QDomElement el = createElementByPath(doc, path);
|
||
|
|
||
|
PairList::ConstIterator it;
|
||
|
for (it = value.begin(); it != value.end(); ++it) {
|
||
|
QDomElement subEl = doc.createElement(tag);
|
||
|
subEl.setAttribute(firstAttr, (*it).first);
|
||
|
subEl.setAttribute(secondAttr, (*it).second);
|
||
|
el.appendChild(subEl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DomPath DomUtil::resolvPathStringExt(const QString pathstring)
|
||
|
{
|
||
|
// parse path
|
||
|
unsigned int i;
|
||
|
QStringList pathParts = QStringList::split('/',pathstring);
|
||
|
DomPath dompath;
|
||
|
for (i=0; i<pathParts.count(); i++)
|
||
|
{
|
||
|
QStringList pathElemParts = QStringList::split('|',pathParts[i],TRUE);
|
||
|
DomPathElement dompathelem;
|
||
|
dompathelem.tagName = pathElemParts[0].simplifyWhiteSpace();
|
||
|
if (pathElemParts.count()>1)
|
||
|
{
|
||
|
// handle attributes
|
||
|
QStringList attrParts = QStringList::split(';',pathElemParts[1]);
|
||
|
for (unsigned int j=0; j<attrParts.count(); j++)
|
||
|
{
|
||
|
QStringList attribSet = QStringList::split('=',attrParts[j]);
|
||
|
if (attribSet.count()<2)
|
||
|
continue;
|
||
|
DomAttribute domattribute;
|
||
|
domattribute.name = attribSet[0].simplifyWhiteSpace();
|
||
|
domattribute.value = attribSet[1].simplifyWhiteSpace();
|
||
|
dompathelem.attribute.append(domattribute);
|
||
|
}
|
||
|
}
|
||
|
if (pathElemParts.count()>2)
|
||
|
dompathelem.matchNumber = pathElemParts[2].toInt();
|
||
|
else
|
||
|
dompathelem.matchNumber = 0; // or else the first
|
||
|
dompath.append(dompathelem);
|
||
|
}
|
||
|
return dompath;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define rightchild !wrongchild
|
||
|
|
||
|
QDomElement DomUtil::elementByPathExt(QDomDocument &doc, const QString &pathstring)
|
||
|
{
|
||
|
DomPath dompath = resolvPathStringExt(pathstring);
|
||
|
QDomElement elem = doc.documentElement();
|
||
|
QDomNodeList children;
|
||
|
QDomElement nextElem = elem;
|
||
|
for (unsigned int j=0; j<dompath.count(); j++)
|
||
|
{
|
||
|
children = nextElem.childNodes();
|
||
|
DomPathElement dompathelement= dompath[j];
|
||
|
bool wrongchild = false;
|
||
|
int matchCount = 0;
|
||
|
for (unsigned int i=0; i<children.count(); i++)
|
||
|
{
|
||
|
wrongchild = false;
|
||
|
QDomElement child = children.item(i).toElement();
|
||
|
QString tag = child.tagName();
|
||
|
tag = dompathelement.tagName;
|
||
|
if (child.tagName() == dompathelement.tagName)
|
||
|
{
|
||
|
for (unsigned int k=0; k<dompathelement.attribute.count(); k++)
|
||
|
{
|
||
|
DomAttribute domattribute = dompathelement.attribute[k];
|
||
|
QDomAttr domattr = child.attributeNode(domattribute.name);
|
||
|
if (domattr.isNull() ||
|
||
|
domattr.value() != domattribute.value)
|
||
|
{
|
||
|
wrongchild = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
wrongchild=true;
|
||
|
if (rightchild)
|
||
|
{
|
||
|
if (dompathelement.matchNumber == matchCount++)
|
||
|
{
|
||
|
nextElem = child;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (wrongchild)
|
||
|
{
|
||
|
QDomElement nullDummy;
|
||
|
nullDummy.clear();
|
||
|
return nullDummy;
|
||
|
}
|
||
|
}
|
||
|
return nextElem;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool DomUtil::openDOMFile(QDomDocument &doc, QString filename)
|
||
|
{
|
||
|
QFile file( filename );
|
||
|
if ( !file.open( IO_ReadOnly ) )
|
||
|
return false;
|
||
|
if ( !doc.setContent( &file ) ) {
|
||
|
file.close();
|
||
|
return false;
|
||
|
}
|
||
|
file.close();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool DomUtil::saveDOMFile(QDomDocument &doc, QString filename)
|
||
|
{
|
||
|
QFile file( filename );
|
||
|
if ( !file.open( IO_ReadWrite | IO_Truncate ) )
|
||
|
return false;
|
||
|
QTextStream t( &file );
|
||
|
t << doc.toString();
|
||
|
file.close();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool DomUtil::removeTextNodes(QDomDocument doc,QString pathExt)
|
||
|
{
|
||
|
QDomElement elem = elementByPathExt(doc,pathExt);
|
||
|
if (elem.isNull())
|
||
|
return false;
|
||
|
QDomNodeList children = elem.childNodes();
|
||
|
for (unsigned int i=0;i<children.count();i++)
|
||
|
if (children.item(i).isText())
|
||
|
elem.removeChild(children.item(i));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool DomUtil::appendText(QDomDocument doc, QString pathExt, QString text)
|
||
|
{
|
||
|
QDomElement elem = elementByPathExt(doc,pathExt);
|
||
|
if (elem.isNull())
|
||
|
return false;
|
||
|
elem.appendChild(doc.createTextNode(text));
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool DomUtil::replaceText(QDomDocument doc, QString pathExt, QString text)
|
||
|
{
|
||
|
if (removeTextNodes(doc,pathExt) &&
|
||
|
appendText(doc,pathExt,text))
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|