File indexing completed on 2023-09-24 04:15:35
0001 /* 0002 This file is part of the syndication library 0003 SPDX-FileCopyrightText: 2006 Frank Osterfeld <osterfeld@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "modelmaker.h" 0009 #include "literal.h" 0010 #include "model.h" 0011 #include "property.h" 0012 #include "rdfvocab.h" 0013 #include "resource.h" 0014 #include "sequence.h" 0015 #include "statement.h" 0016 0017 #include <QDomElement> 0018 #include <QString> 0019 0020 namespace Syndication 0021 { 0022 namespace RDF 0023 { 0024 Model ModelMaker::createFromXML(const QDomDocument &doc) 0025 { 0026 Model model; 0027 0028 if (doc.isNull()) { 0029 return model; 0030 } 0031 0032 const QDomElement rdfNode = doc.documentElement(); 0033 0034 const QDomNodeList list = rdfNode.childNodes(); 0035 0036 for (int i = 0; i < list.length(); ++i) { 0037 if (list.item(i).isElement()) { 0038 const QDomElement el = list.item(i).toElement(); 0039 readResource(model, el); 0040 } 0041 } 0042 0043 return model; 0044 } 0045 0046 ResourcePtr ModelMaker::readResource(Model &model, const QDomElement &el) 0047 { 0048 QString about = QStringLiteral("about"); 0049 QString resource = QStringLiteral("resource"); 0050 0051 ResourcePtr res; 0052 0053 ResourcePtr type = model.createResource(el.namespaceURI() + el.localName()); 0054 0055 if (*type == *(RDFVocab::self()->seq())) { 0056 SequencePtr seq = model.createSequence(el.attribute(about)); 0057 0058 res = seq; 0059 } else { 0060 res = model.createResource(el.attribute(about)); 0061 } 0062 0063 model.addStatement(res, RDFVocab::self()->type(), type); 0064 0065 const QDomNodeList children = el.childNodes(); 0066 0067 bool isSeq = res->isSequence(); 0068 0069 for (int i = 0; i < children.length(); ++i) { 0070 if (children.item(i).isElement()) { 0071 QDomElement ce = children.item(i).toElement(); 0072 0073 PropertyPtr pred = model.createProperty(ce.namespaceURI() + ce.localName()); 0074 0075 if (ce.hasAttribute(resource)) { // referenced Resource via (rdf:)resource 0076 NodePtr obj = model.createResource(ce.attribute(resource)); 0077 0078 if (isSeq && *pred == *(RDFVocab::self()->li())) { 0079 SequencePtr tseq = res.staticCast<Sequence>(); 0080 tseq->append(obj); 0081 } else { 0082 model.addStatement(res, pred, obj); 0083 } 0084 } else if (!ce.text().isEmpty() && ce.lastChildElement().isNull()) { // Literal 0085 NodePtr obj = model.createLiteral(ce.text()); 0086 0087 if (isSeq && *pred == *(RDFVocab::self()->li())) { 0088 SequencePtr tseq = res.staticCast<Sequence>(); 0089 tseq->append(obj); 0090 } else { 0091 model.addStatement(res, pred, obj); 0092 } 0093 } else { // embedded description 0094 QDomElement re = ce.lastChildElement(); 0095 0096 // QString uri = re.attribute(about); 0097 0098 // read recursively 0099 NodePtr obj = readResource(model, re); 0100 0101 if (isSeq && *pred == *(RDFVocab::self()->li())) { 0102 SequencePtr tseq = res.staticCast<Sequence>(); 0103 tseq->append(obj); 0104 } else { 0105 model.addStatement(res, pred, obj); 0106 } 0107 } 0108 0109 // TODO: bag, reification (nice to have, but not important for basic RSS 1.0) 0110 } 0111 } 0112 0113 return res; 0114 } 0115 0116 } // namespace RDF 0117 } // namespace Syndication