markup_validity 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/CHANGELOG.rdoc +6 -0
- data/Manifest.txt +17 -0
- data/README.rdoc +101 -0
- data/Rakefile +19 -0
- data/lib/markup_validity.rb +12 -0
- data/lib/markup_validity/assertions.rb +25 -0
- data/lib/markup_validity/rspec.rb +58 -0
- data/lib/markup_validity/validator.rb +39 -0
- data/lib/markup_validity/xhtml1-strict.xsd +2211 -0
- data/lib/markup_validity/xhtml1-transitional.xsd +2755 -0
- data/lib/markup_validity/xml.xsd +286 -0
- data/spec/matcher_spec.rb +47 -0
- data/test/assets/order.xml +24 -0
- data/test/assets/shipment.xsd +33 -0
- data/test/helper.rb +31 -0
- data/test/test_markup_validity.rb +81 -0
- metadata +99 -0
@@ -0,0 +1,286 @@
|
|
1
|
+
<?xml version='1.0'?>
|
2
|
+
<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
|
3
|
+
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
|
4
|
+
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
5
|
+
xmlns ="http://www.w3.org/1999/xhtml"
|
6
|
+
xml:lang="en">
|
7
|
+
|
8
|
+
<xs:annotation>
|
9
|
+
<xs:documentation>
|
10
|
+
<div>
|
11
|
+
<h1>About the XML namespace</h1>
|
12
|
+
|
13
|
+
<div class="bodytext">
|
14
|
+
<p>
|
15
|
+
This schema document describes the XML namespace, in a form
|
16
|
+
suitable for import by other schema documents.
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
See <a href="http://www.w3.org/XML/1998/namespace.html">
|
20
|
+
http://www.w3.org/XML/1998/namespace.html</a> and
|
21
|
+
<a href="http://www.w3.org/TR/REC-xml">
|
22
|
+
http://www.w3.org/TR/REC-xml</a> for information
|
23
|
+
about this namespace.
|
24
|
+
</p>
|
25
|
+
<p>
|
26
|
+
Note that local names in this namespace are intended to be
|
27
|
+
defined only by the World Wide Web Consortium or its subgroups.
|
28
|
+
The names currently defined in this namespace are listed below.
|
29
|
+
They should not be used with conflicting semantics by any Working
|
30
|
+
Group, specification, or document instance.
|
31
|
+
</p>
|
32
|
+
<p>
|
33
|
+
See further below in this document for more information about <a
|
34
|
+
href="#usage">how to refer to this schema document from your own
|
35
|
+
XSD schema documents</a> and about <a href="#nsversioning">the
|
36
|
+
namespace-versioning policy governing this schema document</a>.
|
37
|
+
</p>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</xs:documentation>
|
41
|
+
</xs:annotation>
|
42
|
+
|
43
|
+
<xs:attribute name="lang">
|
44
|
+
<xs:annotation>
|
45
|
+
<xs:documentation>
|
46
|
+
<div>
|
47
|
+
|
48
|
+
<h3>lang (as an attribute name)</h3>
|
49
|
+
<p>
|
50
|
+
denotes an attribute whose value
|
51
|
+
is a language code for the natural language of the content of
|
52
|
+
any element; its value is inherited. This name is reserved
|
53
|
+
by virtue of its definition in the XML specification.</p>
|
54
|
+
|
55
|
+
</div>
|
56
|
+
<div>
|
57
|
+
<h4>Notes</h4>
|
58
|
+
<p>
|
59
|
+
Attempting to install the relevant ISO 2- and 3-letter
|
60
|
+
codes as the enumerated possible values is probably never
|
61
|
+
going to be a realistic possibility.
|
62
|
+
</p>
|
63
|
+
<p>
|
64
|
+
See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
|
65
|
+
http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
|
66
|
+
and the IANA language subtag registry at
|
67
|
+
<a href="http://www.iana.org/assignments/language-subtag-registry">
|
68
|
+
http://www.iana.org/assignments/language-subtag-registry</a>
|
69
|
+
for further information.
|
70
|
+
</p>
|
71
|
+
<p>
|
72
|
+
The union allows for the 'un-declaration' of xml:lang with
|
73
|
+
the empty string.
|
74
|
+
</p>
|
75
|
+
</div>
|
76
|
+
</xs:documentation>
|
77
|
+
</xs:annotation>
|
78
|
+
<xs:simpleType>
|
79
|
+
<xs:union memberTypes="xs:language">
|
80
|
+
<xs:simpleType>
|
81
|
+
<xs:restriction base="xs:string">
|
82
|
+
<xs:enumeration value=""/>
|
83
|
+
</xs:restriction>
|
84
|
+
</xs:simpleType>
|
85
|
+
</xs:union>
|
86
|
+
</xs:simpleType>
|
87
|
+
</xs:attribute>
|
88
|
+
|
89
|
+
<xs:attribute name="space">
|
90
|
+
<xs:annotation>
|
91
|
+
<xs:documentation>
|
92
|
+
<div>
|
93
|
+
|
94
|
+
<h3>space (as an attribute name)</h3>
|
95
|
+
<p>
|
96
|
+
denotes an attribute whose
|
97
|
+
value is a keyword indicating what whitespace processing
|
98
|
+
discipline is intended for the content of the element; its
|
99
|
+
value is inherited. This name is reserved by virtue of its
|
100
|
+
definition in the XML specification.</p>
|
101
|
+
|
102
|
+
</div>
|
103
|
+
</xs:documentation>
|
104
|
+
</xs:annotation>
|
105
|
+
<xs:simpleType>
|
106
|
+
<xs:restriction base="xs:NCName">
|
107
|
+
<xs:enumeration value="default"/>
|
108
|
+
<xs:enumeration value="preserve"/>
|
109
|
+
</xs:restriction>
|
110
|
+
</xs:simpleType>
|
111
|
+
</xs:attribute>
|
112
|
+
|
113
|
+
<xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
|
114
|
+
<xs:documentation>
|
115
|
+
<div>
|
116
|
+
|
117
|
+
<h3>base (as an attribute name)</h3>
|
118
|
+
<p>
|
119
|
+
denotes an attribute whose value
|
120
|
+
provides a URI to be used as the base for interpreting any
|
121
|
+
relative URIs in the scope of the element on which it
|
122
|
+
appears; its value is inherited. This name is reserved
|
123
|
+
by virtue of its definition in the XML Base specification.</p>
|
124
|
+
|
125
|
+
<p>
|
126
|
+
See <a
|
127
|
+
href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
|
128
|
+
for information about this attribute.
|
129
|
+
</p>
|
130
|
+
</div>
|
131
|
+
</xs:documentation>
|
132
|
+
</xs:annotation>
|
133
|
+
</xs:attribute>
|
134
|
+
|
135
|
+
<xs:attribute name="id" type="xs:ID">
|
136
|
+
<xs:annotation>
|
137
|
+
<xs:documentation>
|
138
|
+
<div>
|
139
|
+
|
140
|
+
<h3>id (as an attribute name)</h3>
|
141
|
+
<p>
|
142
|
+
denotes an attribute whose value
|
143
|
+
should be interpreted as if declared to be of type ID.
|
144
|
+
This name is reserved by virtue of its definition in the
|
145
|
+
xml:id specification.</p>
|
146
|
+
|
147
|
+
<p>
|
148
|
+
See <a
|
149
|
+
href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
|
150
|
+
for information about this attribute.
|
151
|
+
</p>
|
152
|
+
</div>
|
153
|
+
</xs:documentation>
|
154
|
+
</xs:annotation>
|
155
|
+
</xs:attribute>
|
156
|
+
|
157
|
+
<xs:attributeGroup name="specialAttrs">
|
158
|
+
<xs:attribute ref="xml:base"/>
|
159
|
+
<xs:attribute ref="xml:lang"/>
|
160
|
+
<xs:attribute ref="xml:space"/>
|
161
|
+
<xs:attribute ref="xml:id"/>
|
162
|
+
</xs:attributeGroup>
|
163
|
+
|
164
|
+
<xs:annotation>
|
165
|
+
<xs:documentation>
|
166
|
+
<div>
|
167
|
+
|
168
|
+
<h3>Father (in any context at all)</h3>
|
169
|
+
|
170
|
+
<div class="bodytext">
|
171
|
+
<p>
|
172
|
+
denotes Jon Bosak, the chair of
|
173
|
+
the original XML Working Group. This name is reserved by
|
174
|
+
the following decision of the W3C XML Plenary and
|
175
|
+
XML Coordination groups:
|
176
|
+
</p>
|
177
|
+
<blockquote>
|
178
|
+
<p>
|
179
|
+
In appreciation for his vision, leadership and
|
180
|
+
dedication the W3C XML Plenary on this 10th day of
|
181
|
+
February, 2000, reserves for Jon Bosak in perpetuity
|
182
|
+
the XML name "xml:Father".
|
183
|
+
</p>
|
184
|
+
</blockquote>
|
185
|
+
</div>
|
186
|
+
</div>
|
187
|
+
</xs:documentation>
|
188
|
+
</xs:annotation>
|
189
|
+
|
190
|
+
<xs:annotation>
|
191
|
+
<xs:documentation>
|
192
|
+
<div xml:id="usage" id="usage">
|
193
|
+
<h2><a name="usage">About this schema document</a></h2>
|
194
|
+
|
195
|
+
<div class="bodytext">
|
196
|
+
<p>
|
197
|
+
This schema defines attributes and an attribute group suitable
|
198
|
+
for use by schemas wishing to allow <code>xml:base</code>,
|
199
|
+
<code>xml:lang</code>, <code>xml:space</code> or
|
200
|
+
<code>xml:id</code> attributes on elements they define.
|
201
|
+
</p>
|
202
|
+
<p>
|
203
|
+
To enable this, such a schema must import this schema for
|
204
|
+
the XML namespace, e.g. as follows:
|
205
|
+
</p>
|
206
|
+
<pre>
|
207
|
+
<schema . . .>
|
208
|
+
. . .
|
209
|
+
<import namespace="http://www.w3.org/XML/1998/namespace"
|
210
|
+
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
211
|
+
</pre>
|
212
|
+
<p>
|
213
|
+
or
|
214
|
+
</p>
|
215
|
+
<pre>
|
216
|
+
<import namespace="http://www.w3.org/XML/1998/namespace"
|
217
|
+
schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
|
218
|
+
</pre>
|
219
|
+
<p>
|
220
|
+
Subsequently, qualified reference to any of the attributes or the
|
221
|
+
group defined below will have the desired effect, e.g.
|
222
|
+
</p>
|
223
|
+
<pre>
|
224
|
+
<type . . .>
|
225
|
+
. . .
|
226
|
+
<attributeGroup ref="xml:specialAttrs"/>
|
227
|
+
</pre>
|
228
|
+
<p>
|
229
|
+
will define a type which will schema-validate an instance element
|
230
|
+
with any of those attributes.
|
231
|
+
</p>
|
232
|
+
</div>
|
233
|
+
</div>
|
234
|
+
</xs:documentation>
|
235
|
+
</xs:annotation>
|
236
|
+
|
237
|
+
<xs:annotation>
|
238
|
+
<xs:documentation>
|
239
|
+
<div id="nsversioning" xml:id="nsversioning">
|
240
|
+
<h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
|
241
|
+
<div class="bodytext">
|
242
|
+
<p>
|
243
|
+
In keeping with the XML Schema WG's standard versioning
|
244
|
+
policy, this schema document will persist at
|
245
|
+
<a href="http://www.w3.org/2009/01/xml.xsd">
|
246
|
+
http://www.w3.org/2009/01/xml.xsd</a>.
|
247
|
+
</p>
|
248
|
+
<p>
|
249
|
+
At the date of issue it can also be found at
|
250
|
+
<a href="http://www.w3.org/2001/xml.xsd">
|
251
|
+
http://www.w3.org/2001/xml.xsd</a>.
|
252
|
+
</p>
|
253
|
+
<p>
|
254
|
+
The schema document at that URI may however change in the future,
|
255
|
+
in order to remain compatible with the latest version of XML
|
256
|
+
Schema itself, or with the XML namespace itself. In other words,
|
257
|
+
if the XML Schema or XML namespaces change, the version of this
|
258
|
+
document at <a href="http://www.w3.org/2001/xml.xsd">
|
259
|
+
http://www.w3.org/2001/xml.xsd
|
260
|
+
</a>
|
261
|
+
will change accordingly; the version at
|
262
|
+
<a href="http://www.w3.org/2009/01/xml.xsd">
|
263
|
+
http://www.w3.org/2009/01/xml.xsd
|
264
|
+
</a>
|
265
|
+
will not change.
|
266
|
+
</p>
|
267
|
+
<p>
|
268
|
+
Previous dated (and unchanging) versions of this schema
|
269
|
+
document are at:
|
270
|
+
</p>
|
271
|
+
<ul>
|
272
|
+
<li><a href="http://www.w3.org/2009/01/xml.xsd">
|
273
|
+
http://www.w3.org/2009/01/xml.xsd</a></li>
|
274
|
+
<li><a href="http://www.w3.org/2007/08/xml.xsd">
|
275
|
+
http://www.w3.org/2007/08/xml.xsd</a></li>
|
276
|
+
<li><a href="http://www.w3.org/2004/10/xml.xsd">
|
277
|
+
http://www.w3.org/2004/10/xml.xsd</a></li>
|
278
|
+
<li><a href="http://www.w3.org/2001/03/xml.xsd">
|
279
|
+
http://www.w3.org/2001/03/xml.xsd</a></li>
|
280
|
+
</ul>
|
281
|
+
</div>
|
282
|
+
</div>
|
283
|
+
</xs:documentation>
|
284
|
+
</xs:annotation>
|
285
|
+
|
286
|
+
</xs:schema>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'markup_validity'
|
3
|
+
require 'test/helper'
|
4
|
+
|
5
|
+
module Spec
|
6
|
+
module Matchers
|
7
|
+
extend MarkupValidity::TestHelper
|
8
|
+
describe "[actual.should] be_xhtml_transitional" do
|
9
|
+
it "is transitional xhtml" do
|
10
|
+
Matchers.valid_document.should be_xhtml_transitional
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is xhtml" do
|
14
|
+
Matchers.valid_document.should be_xhtml
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is strict xhtml" do
|
18
|
+
Matchers.valid_document.should be_xhtml_strict
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is not transitional xhtml" do
|
22
|
+
Matchers.invalid_document.should_not be_xhtml_transitional
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is not strict xhtml" do
|
26
|
+
Matchers.invalid_document.should_not be_xhtml_strict
|
27
|
+
end
|
28
|
+
|
29
|
+
XSD = File.read(
|
30
|
+
File.expand_path(
|
31
|
+
File.join(File.dirname(__FILE__),'..','test','assets','shipment.xsd')
|
32
|
+
)
|
33
|
+
)
|
34
|
+
XML = File.read(
|
35
|
+
File.join(File.dirname(__FILE__), '..','test', 'assets', 'order.xml')
|
36
|
+
)
|
37
|
+
|
38
|
+
it "is valid given spec" do
|
39
|
+
XML.should be_valid_with_schema XSD
|
40
|
+
end
|
41
|
+
|
42
|
+
it "is not valid given spec" do
|
43
|
+
XML.gsub(/<name>[^<]*<\/name>/, '').should_not be_valid_with_schema XSD
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<shiporder orderid="889923"
|
4
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
5
|
+
xsi:noNamespaceSchemaLocation="shiporder.xsd">
|
6
|
+
<orderperson>John Smith</orderperson>
|
7
|
+
<shipto>
|
8
|
+
<name>Ola Nordmann</name>
|
9
|
+
<address>Langgt 23</address>
|
10
|
+
<city>4000 Stavanger</city>
|
11
|
+
<country>Norway</country>
|
12
|
+
</shipto>
|
13
|
+
<item>
|
14
|
+
<title>Empire Burlesque</title>
|
15
|
+
<note>Special Edition</note>
|
16
|
+
<quantity>1</quantity>
|
17
|
+
<price>10.90</price>
|
18
|
+
</item>
|
19
|
+
<item>
|
20
|
+
<title>Hide your heart</title>
|
21
|
+
<quantity>1</quantity>
|
22
|
+
<price>9.90</price>
|
23
|
+
</item>
|
24
|
+
</shiporder>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
2
|
+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
3
|
+
|
4
|
+
<xs:element name="shiporder">
|
5
|
+
<xs:complexType>
|
6
|
+
<xs:sequence>
|
7
|
+
<xs:element name="orderperson" type="xs:string"/>
|
8
|
+
<xs:element name="shipto">
|
9
|
+
<xs:complexType>
|
10
|
+
<xs:sequence>
|
11
|
+
<xs:element name="name" type="xs:string"/>
|
12
|
+
<xs:element name="address" type="xs:string"/>
|
13
|
+
<xs:element name="city" type="xs:string"/>
|
14
|
+
<xs:element name="country" type="xs:string"/>
|
15
|
+
</xs:sequence>
|
16
|
+
</xs:complexType>
|
17
|
+
</xs:element>
|
18
|
+
<xs:element name="item" maxOccurs="unbounded">
|
19
|
+
<xs:complexType>
|
20
|
+
<xs:sequence>
|
21
|
+
<xs:element name="title" type="xs:string"/>
|
22
|
+
<xs:element name="note" type="xs:string" minOccurs="0"/>
|
23
|
+
<xs:element name="quantity" type="xs:positiveInteger"/>
|
24
|
+
<xs:element name="price" type="xs:decimal"/>
|
25
|
+
</xs:sequence>
|
26
|
+
</xs:complexType>
|
27
|
+
</xs:element>
|
28
|
+
</xs:sequence>
|
29
|
+
<xs:attribute name="orderid" type="xs:string" use="required"/>
|
30
|
+
</xs:complexType>
|
31
|
+
</xs:element>
|
32
|
+
|
33
|
+
</xs:schema>
|
data/test/helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module MarkupValidity
|
2
|
+
module TestHelper
|
3
|
+
def valid_document
|
4
|
+
<<-eoxhtml
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
6
|
+
<head>
|
7
|
+
<title>hello world</title>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
</body>
|
11
|
+
</html>
|
12
|
+
eoxhtml
|
13
|
+
end
|
14
|
+
|
15
|
+
def invalid_document
|
16
|
+
<<-eoxhtml
|
17
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
18
|
+
<head>
|
19
|
+
</head>
|
20
|
+
<body>
|
21
|
+
<p>
|
22
|
+
<p>
|
23
|
+
Hello
|
24
|
+
</p>
|
25
|
+
</p>
|
26
|
+
</body>
|
27
|
+
</html>
|
28
|
+
eoxhtml
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require 'helper'
|
3
|
+
require "markup_validity"
|
4
|
+
|
5
|
+
class TestMarkupValidity < Test::Unit::TestCase
|
6
|
+
include MarkupValidity::TestHelper
|
7
|
+
|
8
|
+
class FakeUnit
|
9
|
+
include MarkupValidity::Assertions
|
10
|
+
|
11
|
+
attr_reader :assertions
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@assertions = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def assert *args
|
18
|
+
@assertions << args
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@fu = FakeUnit.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_line_numbers_do_not_roll_over
|
27
|
+
validator = MarkupValidity::Validator.new('foo')
|
28
|
+
assert !validator.valid?
|
29
|
+
assert_no_match(/-1/, validator.inspect)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_line_numbers_do_not_roll_over_line_1
|
33
|
+
validator = MarkupValidity::Validator.new("\nfoo")
|
34
|
+
assert !validator.valid?
|
35
|
+
assert_no_match(/-1/, validator.inspect)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_valid_xhtml_transitional
|
39
|
+
@fu.assert_xhtml_transitional valid_document
|
40
|
+
assert_equal [true, ''], @fu.assertions.first
|
41
|
+
assert_xhtml_transitional valid_document
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_valid_xhtml
|
45
|
+
@fu.assert_xhtml valid_document
|
46
|
+
assert_equal [true, ''], @fu.assertions.first
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_valid_xhtml_strict
|
50
|
+
@fu.assert_xhtml_strict valid_document
|
51
|
+
assert_equal [true, ''], @fu.assertions.first
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_invalid_xhtml
|
55
|
+
@fu.assert_xhtml_transitional invalid_document
|
56
|
+
assert_equal false, @fu.assertions.first.first
|
57
|
+
assert_match('Missing child element', @fu.assertions.first.last)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_invalid_xhtml_strict
|
61
|
+
@fu.assert_xhtml_strict invalid_document
|
62
|
+
assert_equal false, @fu.assertions.first.first
|
63
|
+
assert_match('Missing child element', @fu.assertions.first.last)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_valid_schema
|
67
|
+
xsd = File.join(File.dirname(__FILE__), 'assets', 'shipment.xsd')
|
68
|
+
xml = File.join(File.dirname(__FILE__), 'assets', 'order.xml')
|
69
|
+
@fu.assert_schema File.read(xsd), File.read(xml)
|
70
|
+
assert_equal [true, ''], @fu.assertions.first
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_invalid_schema
|
74
|
+
xsd = File.join(File.dirname(__FILE__), 'assets', 'shipment.xsd')
|
75
|
+
xml = File.read File.join(File.dirname(__FILE__), 'assets', 'order.xml')
|
76
|
+
xml.gsub!(/<name>[^<]*<\/name>/, '')
|
77
|
+
@fu.assert_schema File.read(xsd), xml
|
78
|
+
assert_equal false, @fu.assertions.first.first
|
79
|
+
assert_match('This element is not', @fu.assertions.first.last)
|
80
|
+
end
|
81
|
+
end
|