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>
41namespace Syndication {
44class 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();
57Syndication::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");
103QDomNode 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));
184QDomDocument 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));
209Parser& Parser::operator=(
const Parser& ) {
return *
this; }
static Format mapTypeToFormat(const QString &type, const QString &src=QString())
maps a mimetype to Format enum according to the Atom 1.0 specification
Format
format of the content.
@ XML
the content is embedded XML
@ EscapedHTML
the content is escaped HTML, (i.e., "<", ">" etc.
@ PlainText
the content is plain text (i.e.
@ Binary
the content is base64-encoded binary content
An Atom 1.0 Entry Document, containing a single Atom entry outside of the context of a feed.
An Atom 1.0 Feed Document, containing metadata describing the feed and a number of entries.
parser implementation for Atom 1.0 and 0.3.
Syndication::SpecificDocumentPtr parse(const Syndication::DocumentSource &source) const
parses either an EntryDocument or a FeedDocument from a document source.
virtual ~Parser()
destructor
Parser()
default constructor
QString format() const
returns the format string for this parser implementation, which is "atom"
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.
Atom parser and model classes, representing Atom 1.0 documents (Atom 0.3 documents are converted by t...
QString atom1Namespace()
namespace used by Atom 1.0 elements
QString atom0_3Namespace()
namespace used by Atom 0.3 elements