diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-07 17:09:39 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2023-04-07 17:09:39 +0100 |
commit | 9652aed5c4711581917230c5dbcd38968cffc7e4 (patch) | |
tree | 4f1dbe7ce880744420d85f07294c90ec6412f129 | |
parent | Move testing import to root (diff) | |
download | gentoobrowse-9652aed5c4711581917230c5dbcd38968cffc7e4.tar.bz2 gentoobrowse-9652aed5c4711581917230c5dbcd38968cffc7e4.tar.xz gentoobrowse-9652aed5c4711581917230c5dbcd38968cffc7e4.zip |
Validate sitemap and atom pages against XSDs
-rw-r--r-- | gentoobrowse/src/Jamfile.jam | 2 | ||||
-rw-r--r-- | gentoobrowse/src/atom.xsd | 426 | ||||
-rw-r--r-- | gentoobrowse/src/sitemap.xsd | 106 | ||||
-rw-r--r-- | gentoobrowse/src/test.cpp | 54 | ||||
-rw-r--r-- | gentoobrowse/src/xml.xsd | 46 | ||||
-rw-r--r-- | gentoobrowse/xslt/home-atom.xslt | 8 | ||||
-rw-r--r-- | gentoobrowse/xslt/news-atom.xslt | 8 | ||||
-rw-r--r-- | gentoobrowse/xslt/user-atom.xslt | 8 |
8 files changed, 628 insertions, 30 deletions
diff --git a/gentoobrowse/src/Jamfile.jam b/gentoobrowse/src/Jamfile.jam index c39ee70..af99f1e 100644 --- a/gentoobrowse/src/Jamfile.jam +++ b/gentoobrowse/src/Jamfile.jam @@ -83,7 +83,7 @@ path-constant me : . ; run test.cpp : -- : - [ sequence.insertion-sort [ glob ../xslt/*.xslt ] ] + [ sequence.insertion-sort [ glob ../xslt/*.xslt ] [ glob *.xsd ] ] : <define>BOOST_TEST_DYN_LINK <define>ROOT=\"$(me)\" diff --git a/gentoobrowse/src/atom.xsd b/gentoobrowse/src/atom.xsd new file mode 100644 index 0000000..f59dfeb --- /dev/null +++ b/gentoobrowse/src/atom.xsd @@ -0,0 +1,426 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + -*- rnc -*- RELAX NG Compact Syntax Grammar for the Atom Format + Specification Version 11 +--> +<!-- + $Revision: 34 $ + $Date: 2009-08-07 18:20:47 -0400 (Fri, 07 Aug 2009) $ + $Author: albertcbrown $ + $HeadURL: file:///var/lib/subversion/cmis/trunk/SchemaProject/schema/ATOM.xsd $ +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" elementFormDefault="qualified" targetNamespace="http://www.w3.org/2005/Atom" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1" version="0.62d"> + <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/> + <!-- Common attributes --> + <xs:attributeGroup name="atomCommonAttributes"> + <xs:attribute ref="xml:base"/> + <xs:attribute ref="xml:lang"/> + <xs:attributeGroup ref="atom:undefinedAttribute"/> + </xs:attributeGroup> + <!-- Text Constructs --> + <xs:attributeGroup name="atomPlainTextConstruct"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="type"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="text"/> + <xs:enumeration value="html"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:group name="atomXHTMLTextConstruct"> + <xs:sequence> + <xs:any minOccurs="0" maxOccurs="unbounded" namespace="http://www.w3.org/1999/xhtml"/> + </xs:sequence> + </xs:group> + <xs:attributeGroup name="atomXHTMLTextConstruct"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="type" use="required"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="xhtml"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:complexType name="atomTextConstruct" mixed="true"> + <xs:group minOccurs="0" ref="atom:atomXHTMLTextConstruct"/> + <xs:attribute name="type"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="text"/> + <xs:enumeration value="html"/> + <xs:enumeration value="xhtml"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + <!-- Person Construct --> + <xs:complexType name="atomPersonConstruct"> + <xs:sequence> + <xs:element ref="atom:name" minOccurs="0" maxOccurs="1"/> + <xs:element ref="atom:uri" minOccurs="0" maxOccurs="1"/> + <xs:element ref="atom:email" minOccurs="0" maxOccurs="1"/> + <xs:group ref="atom:extensionElement" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + <xs:element name="name" type="xs:string"/> + <xs:element name="uri" type="xs:string"/> + <xs:element name="email" type="atom:atomEmailAddress"/> + <!-- Date Construct --> + <xs:complexType name="atomDateConstruct"> + <xs:simpleContent> + <xs:extension base="xs:dateTime"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + <!-- atom:feed --> + <xs:element name="feed" type="atom:feedType"/> + <xs:complexType name="feedType"> + <xs:sequence> + <xs:choice maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="items"/> + </xs:appinfo> + </xs:annotation> + <xs:element ref="atom:author"/> + <xs:element ref="atom:category"/> + <xs:element ref="atom:contributor"/> + <xs:element ref="atom:generator"/> + <xs:element ref="atom:icon"/> + <xs:element ref="atom:id"/> + <xs:element ref="atom:link"/> + <xs:element ref="atom:logo"/> + <xs:element ref="atom:rights"/> + <xs:element ref="atom:subtitle"/> + <xs:element ref="atom:title"/> + <xs:element ref="atom:updated"/> + </xs:choice> + <!-- original atom extension element --> + <xs:group ref="atom:extensionElement"/> + <xs:element minOccurs="0" maxOccurs="unbounded" ref="atom:entry"/> + </xs:sequence> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + <!-- atom:entry --> + <xs:element name="entry" type="atom:entryType"> + </xs:element> + <xs:complexType name="entryType"> + <xs:sequence> + <xs:choice maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="items"/> + </xs:appinfo> + </xs:annotation> + <xs:element ref="atom:author"/> + <xs:element ref="atom:category"/> + <xs:element ref="atom:content"/> + <xs:element ref="atom:contributor"/> + <xs:element ref="atom:id"/> + <xs:element ref="atom:link"/> + <xs:element ref="atom:published"/> + <xs:element ref="atom:rights"/> + <xs:element ref="atom:source"/> + <xs:element ref="atom:summary"/> + <xs:element ref="atom:title"/> + <xs:element ref="atom:updated"/> + </xs:choice> + <!-- Normal ATOM extension element --> + <xs:group ref="atom:extensionElement"/> + </xs:sequence> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + <!-- atom:content --> + <xs:attributeGroup name="atomInlineTextConstruct"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="type"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="text"/> + <xs:enumeration value="html"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:group name="atomInlineOtherConstruct"> + <xs:sequence> + <xs:group minOccurs="0" maxOccurs="unbounded" ref="atom:anyElement"/> + </xs:sequence> + </xs:group> + <xs:attributeGroup name="atomInlineOtherConstruct"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="type"> + <xs:simpleType> + <xs:union memberTypes="atom:atomMediaType"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="xhtml"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:attributeGroup name="atomOutOfLineConstruct"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="type" type="atom:atomMediaType"/> + <xs:attribute name="src" use="required"/> + </xs:attributeGroup> + <xs:element name="content"> + <xs:complexType mixed="true"> + <xs:group minOccurs="0" ref="atom:atomInlineOtherConstruct"/> + <xs:attribute name="type"> + <xs:simpleType> + <xs:union memberTypes="atom:atomMediaType"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="text"/> + <xs:enumeration value="html"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:union memberTypes="atom:atomMediaType"> + <xs:simpleType> + <xs:restriction base="xs:token"> + <xs:enumeration value="xhtml"/> + </xs:restriction> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:union> + </xs:simpleType> + </xs:attribute> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="src"/> + </xs:complexType> + </xs:element> + <!-- atom:author --> + <xs:element name="author" type="atom:atomPersonConstruct"/> + <!-- atom:category --> + <xs:element name="category"> + <xs:complexType> + <xs:complexContent> + <xs:extension base="atom:undefinedContent"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="term" use="required"/> + <xs:attribute name="scheme"/> + <xs:attribute name="label"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + </xs:element> + <!-- atom:contributor --> + <xs:element name="contributor" type="atom:atomPersonConstruct"/> + <!-- atom:generator --> + <xs:element name="generator"> + <xs:complexType mixed="true"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="uri"/> + <xs:attribute name="version"/> + </xs:complexType> + </xs:element> + <!-- atom:icon --> + <xs:element name="icon"> + <xs:complexType mixed="true"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + </xs:element> + <!-- atom:id --> + <xs:element name="id"> + <xs:complexType mixed="true"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + </xs:element> + <!-- atom:logo --> + <xs:element name="logo"> + <xs:complexType mixed="true"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + </xs:element> + <!-- atom:link --> + <xs:element name="link"> + <xs:annotation> + <xs:documentation> + The "atom:link" element defines a reference from an + entry or feed to a Web resource. This specification + assigns no + meaning to the content (if any) of this + element. + </xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:complexContent> + <xs:extension base="atom:undefinedContent"> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + <xs:attribute name="href" use="required"/> + <xs:attribute name="rel"/> + <xs:attribute name="type" type="atom:atomMediaType"/> + <xs:attribute name="hreflang" type="atom:atomLanguageTag"/> + <xs:attribute name="title"/> + <xs:attribute name="length"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + </xs:element> + <!-- atom:published --> + <xs:element name="published" type="atom:atomDateConstruct"/> + <!-- atom:rights --> + <xs:element name="rights" type="atom:atomTextConstruct"/> + <!-- atom:source --> + <xs:element name="source"> + <xs:annotation> + <xs:documentation> + atom:source is used to preserve metadata of a feed + when + an entry is copied from a feed to another feed. + </xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="atom:author"/> + <xs:element ref="atom:category"/> + <xs:element ref="atom:contributor"/> + <xs:element ref="atom:generator"/> + <xs:element ref="atom:icon"/> + <xs:element ref="atom:id"/> + <xs:element ref="atom:link"/> + <xs:element ref="atom:logo"/> + <xs:element ref="atom:rights"/> + <xs:element ref="atom:subtitle"/> + <xs:element ref="atom:title"/> + <xs:element ref="atom:updated"/> + <xs:group ref="atom:extensionElement"/> + </xs:choice> + <xs:attributeGroup ref="atom:atomCommonAttributes"/> + </xs:complexType> + </xs:element> + <!-- atom:subtitle --> + <xs:element name="subtitle" type="atom:atomTextConstruct"/> + <!-- atom:summary --> + <xs:element name="summary" type="atom:atomTextConstruct"/> + <!-- atom:title --> + <xs:element name="title" type="atom:atomTextConstruct"> + <xs:annotation> + <xs:documentation> + The "atom:title" element is a Text construct that + conveys a human- readable title for an entry or feed. + atomTitle = + element atom:title { atomTextConstruct }. + </xs:documentation> + </xs:annotation> + </xs:element> + <!-- atom:updated --> + <xs:element name="updated" type="atom:atomDateConstruct"> + <xs:annotation> + <xs:documentation> + The "atom:updated" element is a Date construct + indicating the most recent instant in time when an entry + or feed was + modified in a way the publisher considers + significant. Therefore, not + all modifications + necessarily result in a changed atom:updated value. + atomUpdated = element atom:updated { atomDateConstruct + }. Publishers + MAY change the value of this element over + time. + </xs:documentation> + </xs:annotation> + </xs:element> + <!-- Low-level simple types --> + <xs:simpleType name="atomNCName"> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + <xs:pattern value="[^:]*"/> + </xs:restriction> + </xs:simpleType> + <!-- Whatever a media type is, it contains at least one slash --> + <xs:simpleType name="atomMediaType"> + <xs:restriction base="xs:string"> + <xs:pattern value=".+/.+"/> + </xs:restriction> + </xs:simpleType> + <!-- As defined in RFC 3066 --> + <xs:simpleType name="atomLanguageTag"> + <xs:restriction base="xs:string"> + <xs:pattern value="[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*"/> + </xs:restriction> + </xs:simpleType> + <!-- + Unconstrained; it's not entirely clear how IRI fit into xsd:anyURI so + let's not try to constrain it here + --> + <!-- Whatever an email address is, it contains at least one @ --> + <xs:simpleType name="atomEmailAddress"> + <xs:restriction base="xs:string"> + <xs:pattern value=".+@.+"/> + </xs:restriction> + </xs:simpleType> + <!-- Simple Extension --> + <xs:group name="extensionElement"> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="anyOther"/> + </xs:appinfo> + </xs:annotation> + </xs:any> + <xs:any namespace="##local" processContents="lax" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="anyLocal"/> + </xs:appinfo> + </xs:annotation> + </xs:any> + </xs:sequence> + </xs:group> + <xs:attributeGroup name="undefinedAttribute"> + <xs:anyAttribute namespace="##other" processContents="lax"/> + </xs:attributeGroup> + <xs:complexType name="undefinedContent"> + <xs:sequence> + <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="anyOther"/> + </xs:appinfo> + </xs:annotation> + </xs:any> + <xs:any namespace="##local" processContents="lax" minOccurs="0" maxOccurs="unbounded"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="anyLocal"/> + </xs:appinfo> + </xs:annotation> + </xs:any> + </xs:sequence> + <!-- + <xs:group minOccurs="0" maxOccurs="unbounded" + ref="atom:anyForeignElement" /> + --> + </xs:complexType> + <xs:group name="anyElement"> + <xs:sequence> + <xs:any processContents="lax"/> + </xs:sequence> + </xs:group> + <xs:group name="anyForeignElement"> + <xs:sequence> + <xs:any namespace="##other" processContents="lax"/> + <xs:any namespace="##local" processContents="lax"/> + </xs:sequence> + </xs:group> + <!-- XHTML --> + <xs:group name="anyXHTML"> + <xs:sequence> + <xs:any namespace="http://www.w3.org/1999/xhtml" processContents="lax"/> + </xs:sequence> + </xs:group> +</xs:schema> diff --git a/gentoobrowse/src/sitemap.xsd b/gentoobrowse/src/sitemap.xsd new file mode 100644 index 0000000..36d7a95 --- /dev/null +++ b/gentoobrowse/src/sitemap.xsd @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" targetNamespace="http://www.sitemaps.org/schemas/sitemap/0.9" elementFormDefault="qualified">
+ <xsd:annotation>
+ <xsd:documentation>
+ XML Schema for Sitemap files.
+ Last Modifed 2008-03-26
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:element name="urlset">
+ <xsd:annotation>
+ <xsd:documentation>
+ Container for a set of up to 50,000 document elements.
+ This is the root element of the XML file.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="strict"/>
+ <xsd:element name="url" type="tUrl" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:complexType name="tUrl">
+ <xsd:annotation>
+ <xsd:documentation>
+ Container for the data needed to describe a document to crawl.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="loc" type="tLoc"/>
+ <xsd:element name="lastmod" type="tLastmod" minOccurs="0"/>
+ <xsd:element name="changefreq" type="tChangeFreq" minOccurs="0"/>
+ <xsd:element name="priority" type="tPriority" minOccurs="0"/>
+ <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="strict"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:simpleType name="tLoc">
+ <xsd:annotation>
+ <xsd:documentation>
+ REQUIRED: The location URI of a document.
+ The URI must conform to RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt).
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:anyURI">
+ <xsd:minLength value="12"/>
+ <xsd:maxLength value="2048"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="tLastmod">
+ <xsd:annotation>
+ <xsd:documentation>
+ OPTIONAL: The date the document was last modified. The date must conform
+ to the W3C DATETIME format (http://www.w3.org/TR/NOTE-datetime).
+ Example: 2005-05-10
+ Lastmod may also contain a timestamp.
+ Example: 2005-05-10T17:33:30+08:00
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:union>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:date"/>
+ </xsd:simpleType>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:dateTime"/>
+ </xsd:simpleType>
+ </xsd:union>
+ </xsd:simpleType>
+ <xsd:simpleType name="tChangeFreq">
+ <xsd:annotation>
+ <xsd:documentation>
+ OPTIONAL: Indicates how frequently the content at a particular URL is
+ likely to change. The value "always" should be used to describe
+ documents that change each time they are accessed. The value "never"
+ should be used to describe archived URLs. Please note that web
+ crawlers may not necessarily crawl pages marked "always" more often.
+ Consider this element as a friendly suggestion and not a command.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="always"/>
+ <xsd:enumeration value="hourly"/>
+ <xsd:enumeration value="daily"/>
+ <xsd:enumeration value="weekly"/>
+ <xsd:enumeration value="monthly"/>
+ <xsd:enumeration value="yearly"/>
+ <xsd:enumeration value="never"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="tPriority">
+ <xsd:annotation>
+ <xsd:documentation>
+ OPTIONAL: The priority of a particular URL relative to other pages
+ on the same site. The value for this element is a number between
+ 0.0 and 1.0 where 0.0 identifies the lowest priority page(s).
+ The default priority of a page is 0.5. Priority is used to select
+ between pages on your site. Setting a priority of 1.0 for all URLs
+ will not help you, as the relative priority of pages on your site
+ is what will be considered.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:decimal">
+ <xsd:minInclusive value="0.0"/>
+ <xsd:maxInclusive value="1.0"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/gentoobrowse/src/test.cpp b/gentoobrowse/src/test.cpp index fd4166b..01ffa76 100644 --- a/gentoobrowse/src/test.cpp +++ b/gentoobrowse/src/test.cpp @@ -6,6 +6,7 @@ #include <filesystem> #include <fstream> #include <libxml++/parsers/domparser.h> +#include <libxml++/validators/xsdvalidator.h> #include <testRequest.h> #include <tidy.h> @@ -36,13 +37,16 @@ public: hdr["Accept-Encoding"] = "gzip, deflate, sdch"; hdr["Accept-Language"] = "en-GB,en;q=0.8"; } +}; +template<typename T = void> class ChromiumRequestT : public ChromiumRequest { + using ChromiumRequest::ChromiumRequest; - virtual void standardAssertions(const char * name) = 0; + virtual T standardAssertions(const char * name) = 0; }; -class ChromiumRequestHtml : public ChromiumRequest { +class ChromiumRequestHtml : public ChromiumRequestT<> { public: - ChromiumRequestHtml(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequest(c, m, p) + ChromiumRequestHtml(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequestT(c, m, p) { hdr["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; } @@ -74,9 +78,9 @@ public: } }; -class ChromiumRequest404 : public ChromiumRequest { +class ChromiumRequest404 : public ChromiumRequestT<> { public: - ChromiumRequest404(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequest(c, m, p) { } + ChromiumRequest404(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequestT(c, m, p) { } virtual void standardAssertions(const char *) override @@ -86,11 +90,11 @@ public: } }; -class ChromiumRequestDefaultXml : public ChromiumRequest { +class ChromiumRequestDefaultXml : public ChromiumRequestT<std::unique_ptr<xmlpp::DomParser>> { public: - using ChromiumRequest::ChromiumRequest; + using ChromiumRequestT::ChromiumRequestT; - virtual void + virtual std::unique_ptr<xmlpp::DomParser> standardAssertions(const char *) override { auto h = getResponseHeaders(); @@ -98,8 +102,17 @@ public: BOOST_REQUIRE_EQUAL(h["Content-Type"], "application/xml"); BOOST_TEST_INFO(this->output.view()); BOOST_REQUIRE_NE(this->output.view().find("<?xml version"), std::string_view::npos); - xmlpp::DomParser p; - p.parse_stream(this->output); + auto p = std::make_unique<xmlpp::DomParser>(); + p->parse_stream(this->output); + return p; + } + + void + xsdAssertions(const char * name, const std::filesystem::path & xsd) + { + auto doc = standardAssertions(name); + xmlpp::XsdValidator validator {xsd}; + validator.validate(doc->get_document()); } }; @@ -111,14 +124,14 @@ public: } }; -class ChromiumRequestAtom : public ChromiumRequest { +class ChromiumRequestAtom : public ChromiumRequestXml { public: - ChromiumRequestAtom(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequest(c, m, p) + ChromiumRequestAtom(const Core * c, HttpMethod m, const std::string & p) : ChromiumRequestXml(c, m, p) { hdr["Accept"] = "application/atom+xml"; } - virtual void + virtual std::unique_ptr<xmlpp::DomParser> standardAssertions(const char *) override { auto h = getResponseHeaders(); @@ -126,8 +139,9 @@ public: BOOST_REQUIRE_EQUAL(h["Content-Type"], "application/atom+xml"); BOOST_TEST_INFO(this->output.view()); BOOST_REQUIRE_NE(this->output.view().find("<?xml version"), std::string_view::npos); - xmlpp::DomParser p; - p.parse_stream(this->output); + auto p = std::make_unique<xmlpp::DomParser>(); + p->parse_stream(this->output); + return p; } }; @@ -261,35 +275,35 @@ BOOST_AUTO_TEST_CASE(search_sitemap) { ChromiumRequestXml request(this, HttpMethod::GET, "/sitemap.xml"); process(&request); - request.standardAssertions(typeid(*this).name()); + request.xsdAssertions(typeid(*this).name(), rootDir / "sitemap.xsd"); } BOOST_AUTO_TEST_CASE(search_sitemap_dfl) { ChromiumRequestDefaultXml request(this, HttpMethod::GET, "/sitemap.xml"); process(&request); - request.standardAssertions(typeid(*this).name()); + request.xsdAssertions(typeid(*this).name(), rootDir / "sitemap.xsd"); } BOOST_AUTO_TEST_CASE(home_atom) { ChromiumRequestAtom request(this, HttpMethod::GET, "/"); process(&request); - request.standardAssertions(typeid(*this).name()); + request.xsdAssertions(typeid(*this).name(), rootDir / "atom.xsd"); } BOOST_AUTO_TEST_CASE(news_atom) { ChromiumRequestAtom request(this, HttpMethod::GET, "/news"); process(&request); - request.standardAssertions(typeid(*this).name()); + request.xsdAssertions(typeid(*this).name(), rootDir / "atom.xsd"); } BOOST_AUTO_TEST_CASE(user_atom) { ChromiumRequestAtom request(this, HttpMethod::GET, "/atom/randomdan"); process(&request); - request.standardAssertions(typeid(*this).name()); + request.xsdAssertions(typeid(*this).name(), rootDir / "atom.xsd"); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/gentoobrowse/src/xml.xsd b/gentoobrowse/src/xml.xsd new file mode 100644 index 0000000..0ca0876 --- /dev/null +++ b/gentoobrowse/src/xml.xsd @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Revision: 34 $ + $Date: 2009-08-07 18:20:47 -0400 (Fri, 07 Aug 2009) $ + $Author: albertcbrown $ + $HeadURL: file:///var/lib/subversion/cmis/trunk/SchemaProject/schema/xml.xsd $ +--> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3.org/XML/1998/namespace" xml:lang="en"> + <xsd:attribute name="lang"> + <xsd:simpleType> + <xsd:union memberTypes="xsd:language"> + <xsd:simpleType> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value=""/> + </xsd:restriction> + </xsd:simpleType> + </xsd:union> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="space"> + <xsd:simpleType> + <xsd:restriction base="xsd:NCName"> + <xsd:enumeration value="default"/> + <xsd:enumeration value="preserve"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:attribute> + <xsd:attribute name="base" type="xsd:anyURI"> + <xsd:annotation> + <xsd:documentation>See http://www.w3.org/TR/xmlbase/ for + information about this attribute.</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="id" type="xsd:ID"> + <xsd:annotation> + <xsd:documentation>See http://www.w3.org/TR/xml-id/ for + information about this attribute.</xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attributeGroup name="specialAttrs"> + <xsd:attribute ref="xml:base"/> + <xsd:attribute ref="xml:lang"/> + <xsd:attribute ref="xml:space"/> + <xsd:attribute ref="xml:id"/> + </xsd:attributeGroup> +</xsd:schema> diff --git a/gentoobrowse/xslt/home-atom.xslt b/gentoobrowse/xslt/home-atom.xslt index 5cd854a..1f80744 100644 --- a/gentoobrowse/xslt/home-atom.xslt +++ b/gentoobrowse/xslt/home-atom.xslt @@ -57,9 +57,11 @@ <name> <xsl:value-of select="package/detail/maintainername" /> </name> - <email> - <xsl:value-of select="package/detail/maintainer" /> - </email> + <xsl:if test="package/detail/maintainer"> + <email> + <xsl:value-of select="package/detail/maintainer" /> + </email> + </xsl:if> </author> </entry> </xsl:template> diff --git a/gentoobrowse/xslt/news-atom.xslt b/gentoobrowse/xslt/news-atom.xslt index bf4350d..11c2006 100644 --- a/gentoobrowse/xslt/news-atom.xslt +++ b/gentoobrowse/xslt/news-atom.xslt @@ -69,9 +69,11 @@ <name> <xsl:value-of select="authorname" /> </name> - <email> - <xsl:value-of select="authoremail" /> - </email> + <xsl:if test="authoremail"> + <email> + <xsl:value-of select="authoremail" /> + </email> + </xsl:if> </author> </entry> </xsl:template> diff --git a/gentoobrowse/xslt/user-atom.xslt b/gentoobrowse/xslt/user-atom.xslt index 32b36e9..b52dc78 100644 --- a/gentoobrowse/xslt/user-atom.xslt +++ b/gentoobrowse/xslt/user-atom.xslt @@ -60,9 +60,11 @@ <name> <xsl:value-of select="$package/maintainername" /> </name> - <email> - <xsl:value-of select="$package/maintainer" /> - </email> + <xsl:if test="$package/maintainer"> + <email> + <xsl:value-of select="$package/maintainer" /> + </email> + </xsl:if> </author> </entry> </xsl:template> |