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.
QString atom1Namespace()
namespace used by Atom 1.0 elements
QString atom0_3Namespace()
namespace used by Atom 0.3 elements