modelmaker.cpp
00001 /* 00002 * This file is part of the syndication library 00003 * 00004 * Copyright (C) 2006 Frank Osterfeld <osterfeld@kde.org> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 */ 00022 00023 #include "modelmaker.h" 00024 #include "literal.h" 00025 #include "model.h" 00026 #include "property.h" 00027 #include "rdfvocab.h" 00028 #include "resource.h" 00029 #include "sequence.h" 00030 #include "statement.h" 00031 00032 #include <QtXml/QDomElement> 00033 #include <QtCore/QString> 00034 00035 namespace Syndication { 00036 namespace RDF { 00037 00038 00039 Model ModelMaker::createFromXML(const QDomDocument& doc) 00040 { 00041 Model model; 00042 00043 if (doc.isNull()) 00044 return model; 00045 00046 QDomElement rdfNode = doc.documentElement(); 00047 00048 QDomNodeList list = rdfNode.childNodes(); 00049 00050 for (uint i = 0; i < list.length(); ++i) 00051 { 00052 if (list.item(i).isElement()) 00053 { 00054 QDomElement el = list.item(i).toElement(); 00055 readResource(model, el); 00056 } 00057 } 00058 00059 return model; 00060 } 00061 00062 ResourcePtr ModelMaker::readResource(Model& model, const QDomElement& el) 00063 { 00064 QString rdfns = RDFVocab::self()->namespaceURI(); 00065 QString about = QLatin1String("about"); 00066 QString resource = QLatin1String("resource"); 00067 QString descriptionStr = QLatin1String("Description"); 00068 00069 ResourcePtr res; 00070 00071 ResourcePtr type = model.createResource(el.namespaceURI() + el.localName()); 00072 00073 if (*type == *(RDFVocab::self()->seq())) 00074 { 00075 SequencePtr seq = model.createSequence(el.attribute(about)); 00076 00077 res = seq; 00078 } 00079 else 00080 { 00081 res = model.createResource(el.attribute(about)); 00082 } 00083 00084 model.addStatement(res, RDFVocab::self()->type(), type); 00085 00086 QDomNodeList children = el.childNodes(); 00087 00088 bool isSeq = res->isSequence(); 00089 00090 for (uint i = 0; i < children.length(); ++i) 00091 { 00092 if (children.item(i).isElement()) 00093 { 00094 QDomElement ce = children.item(i).toElement(); 00095 00096 PropertyPtr pred = model.createProperty(ce.namespaceURI() + ce.localName()); 00097 00098 if (ce.hasAttribute(resource)) // referenced Resource via (rdf:)resource 00099 { 00100 NodePtr obj = model.createResource(ce.attribute(resource)); 00101 00102 if (isSeq && *pred == *(RDFVocab::self()->li())) 00103 { 00104 SequencePtr tseq = boost::static_pointer_cast<Sequence>(res); 00105 tseq->append(obj); 00106 } 00107 else 00108 model.addStatement(res, pred, obj); 00109 } 00110 else if (!ce.text().isEmpty() && ce.lastChildElement().isNull()) // Literal 00111 { 00112 NodePtr obj = model.createLiteral(ce.text()); 00113 00114 if (isSeq && *pred == *(RDFVocab::self()->li())) 00115 { 00116 SequencePtr tseq = boost::static_pointer_cast<Sequence>(res); 00117 tseq->append(obj); 00118 } 00119 else 00120 model.addStatement(res, pred, obj); 00121 } 00122 else // embedded description 00123 { 00124 QDomElement re = ce.lastChildElement(); 00125 00126 QString uri = re.attribute(about); 00127 00128 // read recursively 00129 NodePtr obj = readResource(model, re); 00130 00131 if (isSeq && *pred == *(RDFVocab::self()->li())) 00132 { 00133 SequencePtr tseq = boost::static_pointer_cast<Sequence>(res); 00134 tseq->append(obj); 00135 } 00136 else 00137 model.addStatement(res, pred, obj); 00138 00139 } 00140 00141 //TODO: bag, reification (nice to have, but not important for basic RSS 1.0) 00142 } 00143 } 00144 00145 return res; 00146 } 00147 00148 } // namespace RDF 00149 } // namespace Syndication