24 #include "constants.h"
28 #include <documentsource.h>
30 #include <QtXml/QDomAttr>
31 #include <QtXml/QDomDocument>
32 #include <QtXml/QDomElement>
33 #include <QtXml/QDomNamedNodeMap>
34 #include <QtXml/QDomNode>
35 #include <QtXml/QDomNodeList>
37 #include <QtCore/QHash>
38 #include <QtCore/QRegExp>
39 #include <QtCore/QString>
41 namespace Syndication {
44 class Parser::ParserPrivate
47 static QDomDocument convertAtom0_3(
const QDomDocument& document);
48 static QDomNode convertNode(QDomDocument& doc,
const QDomNode& node,
const QHash<QString, QString>& nameMapper);
53 QDomElement root = source.asDomDocument().documentElement();
57 Syndication::SpecificDocumentPtr
Parser::parse(
const Syndication::DocumentSource& source)
const
59 QDomDocument doc = source.asDomDocument();
67 QDomElement feed = doc.namedItem(QLatin1String(
"feed")).toElement();
69 bool feedValid = !feed.isNull();
71 if (feedValid && feed.attribute(QLatin1String(
"version"))
72 == QLatin1String(
"0.3"))
74 doc = ParserPrivate::convertAtom0_3(doc);
75 feed = doc.namedItem(QLatin1String(
"feed")).toElement();
79 feedValid = !feed.isNull() && feed.namespaceURI() ==
atom1Namespace();
86 QDomElement entry = doc.namedItem(QLatin1String(
"entry")).toElement();
87 bool entryValid = !entry.isNull() && entry.namespaceURI() ==
atom1Namespace();
100 return QLatin1String(
"atom");
103 QDomNode Parser::ParserPrivate::convertNode(QDomDocument& doc,
const QDomNode& node,
const QHash<QString, QString>& nameMapper)
105 if (!node.isElement())
106 return node.cloneNode(
true);
109 QDomElement oldEl = node.toElement();
112 QString newNS = isAtom03Element ?
atom1Namespace() : node.namespaceURI();
114 QString newName = node.localName();
117 if (isAtom03Element && nameMapper.contains(node.localName()))
118 newName = nameMapper[node.localName()];
120 QDomElement newEl = doc.createElementNS(newNS, newName);
122 QDomNamedNodeMap attributes = oldEl.attributes();
125 for (
int i = 0; i < attributes.count(); ++i)
127 QDomAttr attr = attributes.item(i).toAttr();
128 if (attr.namespaceURI().isEmpty())
129 newEl.setAttribute(attr.name(), attr.value());
131 newEl.setAttributeNS(attr.namespaceURI(), attr.name(), attr.value());
135 && (newName == QLatin1String(
"title")
136 || newName == QLatin1String(
"rights")
137 || newName == QLatin1String(
"subtitle")
138 || newName == QLatin1String(
"summary"));
144 QString oldType = newEl.attribute(QLatin1String(
"type"), QLatin1String(
"text/plain") );
151 newType = QLatin1String(
"xhtml");
154 newType = QLatin1String(
"html");
159 newType = QLatin1String(
"text");
163 newEl.setAttribute(QLatin1String(
"type"), newType);
169 bool isGenerator = newNS ==
atom1Namespace() && newName == QLatin1String(
"generator");
170 if (isGenerator && newEl.hasAttribute(QLatin1String(
"url")))
171 newEl.setAttribute(QLatin1String(
"uri"), newEl.attribute(QLatin1String(
"url")));
175 QDomNodeList children = node.childNodes();
176 for (
int i = 0; i < children.count(); ++i)
178 newEl.appendChild(convertNode(doc, children.item(i), nameMapper));
184 QDomDocument Parser::ParserPrivate::convertAtom0_3(
const QDomDocument& doc03)
186 QDomDocument doc = doc03.cloneNode(
false).toDocument();
189 QHash<QString, QString> nameMapper;
190 nameMapper.insert(QLatin1String(
"issued"), QLatin1String(
"published"));
191 nameMapper.insert(QLatin1String(
"modified"), QLatin1String(
"updated"));
192 nameMapper.insert(QLatin1String(
"url"), QLatin1String(
"uri"));
193 nameMapper.insert(QLatin1String(
"copyright"), QLatin1String(
"rights"));
194 nameMapper.insert(QLatin1String(
"tagline"), QLatin1String(
"subtitle"));
196 QDomNodeList children = doc03.childNodes();
198 for (
int i = 0; i < children.count(); ++i)
200 doc.appendChild(convertNode(doc, children.item(i), nameMapper));
209 Parser& Parser::operator=(
const Parser& ) {
return *
this; }
the content is escaped HTML, (i.e., "<", ">" etc.
Syndication::SpecificDocumentPtr parse(const Syndication::DocumentSource &source) const
parses either an EntryDocument or a FeedDocument from a document source.
bool accept(const Syndication::DocumentSource &source) const
returns whether the source looks like an Atom 1.0 or 0.3 document, by checking the root element...
the content is plain text (i.e.
An Atom 1.0 Feed Document, containing metadata describing the feed and a number of entries...
the content is base64-encoded binary content
QString atom1Namespace()
namespace used by Atom 1.0 elements
Parser()
default constructor
QString atom0_3Namespace()
namespace used by Atom 0.3 elements
the content is embedded XML
static Format mapTypeToFormat(const QString &type, const QString &src=QString())
maps a mimetype to Format enum according to the Atom 1.0 specification
QString format() const
returns the format string for this parser implementation, which is "atom"
Format
format of the content.
virtual ~Parser()
destructor
parser implementation for Atom 1.0 and 0.3.
An Atom 1.0 Entry Document, containing a single Atom entry outside of the context of a feed...