// *** ASSERT *** \\
Assert.True(!res.LastUpdatedTime.Equals(new DateTimeOffset()));
}
+
+ [Fact]
+ [ActiveIssue(24894)]
+ public static void AtomEntryPositiveTest()
+ {
+ string filePath = @"brief-entry-noerror.xml";
+ string serializeFilePath = Path.GetTempFileName();
+
+ try
+ {
+ SyndicationItem feedObjct = null;
+ using (XmlReader reader = XmlReader.Create(filePath))
+ {
+ feedObjct = SyndicationItem.Load(reader);
+ reader.Close();
+ }
+
+ using (XmlWriter writer = XmlWriter.Create(serializeFilePath))
+ {
+ Atom10ItemFormatter atomformatter = new Atom10ItemFormatter(feedObjct);
+ atomformatter.WriteTo(writer);
+ writer.Close();
+ }
+ // compare file filePath and serializeFilePath
+ XmlDiff diff = new XmlDiff()
+ {
+ Option = XmlDiffOption.IgnoreComments | XmlDiffOption.IgnorePrefix | XmlDiffOption.IgnoreWhitespace | XmlDiffOption.IgnoreChildOrder | XmlDiffOption.IgnoreAttributeOrder
+ };
+ Assert.True(diff.Compare(filePath, serializeFilePath));
+ }
+ finally
+ {
+ File.Delete(serializeFilePath);
+ }
+ }
+
+ [Fact]
+ [ActiveIssue(24894)]
+ public static void AtomEntryPositiveTest_write()
+ {
+ string filePath = @"AtomEntryTest.xml";
+ string serializeFilePath = Path.GetTempFileName();
+
+ SyndicationItem item = new SyndicationItem("SyndicationFeed released for .net Core", "A lot of text describing the release of .net core feature", new Uri("http://contoso.com/news/path"));
+ item.Id = "uuid:43481a10-d881-40d1-adf2-99b438c57e21;id=1";
+ item.LastUpdatedTime = new DateTimeOffset(Convert.ToDateTime("2017-10-11T11:25:55Z"));
+
+ try
+ {
+ using (XmlWriter writer = XmlWriter.Create(serializeFilePath))
+ {
+ Atom10ItemFormatter f = new Atom10ItemFormatter(item);
+ f.WriteTo(writer);
+ writer.Close();
+ }
+
+ XmlDiff diff = new XmlDiff()
+ {
+ Option = XmlDiffOption.IgnoreComments | XmlDiffOption.IgnorePrefix | XmlDiffOption.IgnoreWhitespace | XmlDiffOption.IgnoreChildOrder | XmlDiffOption.IgnoreAttributeOrder
+ };
+ Assert.True(diff.Compare(filePath, serializeFilePath));
+ }
+ finally
+ {
+ File.Delete(serializeFilePath);
+ }
+ }
+
+ [Fact]
+ [ActiveIssue(24894)]
+ public static void AtomFeedPositiveTest()
+ {
+ string dataFile = @"atom_feeds.dat";
+ List<string> fileList = GetTestFilesForFeedTest(dataFile);
+
+ foreach (string file in fileList)
+ {
+ string serializeFilePath = Path.GetTempFileName();
+ try
+ {
+ SyndicationFeed feedObjct;
+
+ using (XmlReader reader = XmlReader.Create(file))
+ {
+ feedObjct = SyndicationFeed.Load(reader);
+ reader.Close();
+ }
+
+ using (XmlWriter writer = XmlWriter.Create(serializeFilePath))
+ {
+ Atom10FeedFormatter f = new Atom10FeedFormatter(feedObjct);
+ f.WriteTo(writer);
+ writer.Close();
+ }
+
+ CompareHelper ch = new CompareHelper
+ {
+ Diff = new XmlDiff()
+ {
+ Option = XmlDiffOption.IgnoreComments | XmlDiffOption.IgnorePrefix | XmlDiffOption.IgnoreWhitespace | XmlDiffOption.IgnoreChildOrder | XmlDiffOption.IgnoreAttributeOrder
+ },
+ AllowableDifferences = GetAtomFeedPositiveTestAllowableDifferences()
+ };
+ Assert.True(ch.Compare(file, serializeFilePath), $"Failed File Name:{file}");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine();
+ Console.WriteLine("------------------------------");
+ Console.WriteLine($"Failed File Name:{file}");
+ throw e;
+ }
+ finally
+ {
+ File.Delete(serializeFilePath);
+ }
+ }
+ }
+
+ private static List<AllowableDifference> GetAtomFeedPositiveTestAllowableDifferences()
+ {
+ return new List<AllowableDifference>(new AllowableDifference[]
+ {
+ new AllowableDifference("<content xmlns=\"http://www.w3.org/2005/Atom\" />","<content type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<content>","<content type=\"text\">"),
+ new AllowableDifference("<content src=\"http://example.org/2003/12/13/atom03\" xmlns=\"http://www.w3.org/2005/Atom\" />","<content src=\"http://example.org/2003/12/13/atom03\" type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<content src=\" http://www.example.com/doc.pdf\" type=\"application/pdf\" xmlns=\"http://www.w3.org/2005/Atom\" />","<content src=\"http://www.example.com/doc.pdf\" type=\"application/pdf\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("2003-12-13T08:29:29-04:00","2003-12-13T12:29:29Z"),
+ new AllowableDifference("2003-12-13T18:30:02+01:00","2003-12-13T17:30:02Z"),
+ new AllowableDifference("2002-12-31T19:20:30+01:00","2002-12-31T18:20:30Z"),
+ new AllowableDifference("2004-12-27T11:12:01-05:00","2004-12-27T16:12:01Z"),
+ new AllowableDifference("<title>","<title type=\"text\">"),
+ new AllowableDifference("<subtitle>","<subtitle type=\"text\">"),
+ new AllowableDifference("<subtitle xmlns=\"http://www.w3.org/2005/Atom\" />","<subtitle type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<title xmlns=\"http://www.w3.org/2005/Atom\" />","<title type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<title />","<title type=\"text\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<atom:title>","<title type=\"text\">"),
+ new AllowableDifference("<summary>","<summary type=\"text\">"),
+ new AllowableDifference("<atom:summary>","<summary type=\"text\">"),
+ new AllowableDifference("<generator uri=\"http://www.example.com/\" version=\"1.0\">", "<generator>"),
+ new AllowableDifference("<generator uri=\"/generator\" xmlns=\"http://www.w3.org/2005/Atom\" />", "<generator xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<generator uri=\"/generator\">", "<generator>"),
+ new AllowableDifference("<generator uri=\"misc/Colophon\">", "<generator>"),
+ new AllowableDifference("<generator uri=\"http://www.example.com/ \" version=\"1.0\">", "<generator>"),
+ new AllowableDifference("<rights>","<rights type=\"text\">"),
+ new AllowableDifference("<link href=\"http://example.com\" xmlns=\"http://www.w3.org/2005/Atom\" />","<link href=\"http://example.com/\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<link href=\" http://example.org/ \" xmlns=\"http://www.w3.org/2005/Atom\" />","<link href=\"http://example.org/\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<feed xml:lang=\"\" xmlns=\"http://www.w3.org/2005/Atom\">","<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<entry xmlns:xh=\"http://www.w3.org/1999/xhtml\">","<entry>"),
+ new AllowableDifference("<xh:div>","<xh:div xmlns:xh=\"http://www.w3.org/1999/xhtml\">"),
+ new AllowableDifference("<summary type=\"xhtml\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">","<summary type=\"xhtml\">"),
+ new AllowableDifference("<xhtml:a href=\"http://example.com/\">","<xhtml:a href=\"http://example.com/\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">"),
+ new AllowableDifference("<feed xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\" xmlns=\"http://www.w3.org/2005/Atom\">","<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<trackback:ping>", "<trackback:ping xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\">"),
+ new AllowableDifference("<feed xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<author rdf:parseType=\"Resource\">", "<author xmlns:a=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" a:parseType=\"Resource\">"),
+ new AllowableDifference("<foaf:homepage rdf:resource=\"http://jondoe.example.org/\">", "<foaf:homepage xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" rdf:resource=\"http://jondoe.example.org/\">"),
+ new AllowableDifference("<foaf:weblog rdf:resource=\"http://jondoe.example.org/blog/\">", "<foaf:weblog xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" rdf:resource=\"http://jondoe.example.org/blog/\">"),
+ new AllowableDifference("<foaf:workplaceHomepage rdf:resource=\"http://DoeCorp.example.com/\">", "<foaf:workplaceHomepage xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" rdf:resource=\"http://DoeCorp.example.com/\">"),
+ new AllowableDifference("<dc:description>", "<dc:description xmlns:dc=\"http://purl.org/dc/elements/1.1/\">"),
+ new AllowableDifference("<entry rdf:parseType=\"Resource\">", "<entry xmlns:a=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" a:parseType=\"Resource\">"),
+ new AllowableDifference("<foaf:primaryTopic rdf:parseType=\"Resource\">", "<foaf:primaryTopic xmlns:foaf=\"http://xmlns.com/foaf/0.1/\" rdf:parseType=\"Resource\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">"),
+ new AllowableDifference("<link href=\"http://example.org/\" rdf:resource=\"http://example.org/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns=\"http://www.w3.org/2005/Atom\" />", "<link xmlns:a=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" href=\"http://example.org/\" a:resource=\"http://example.org/\" xmlns=\"http://www.w3.org/2005/Atom\" />"),
+ new AllowableDifference("<feed xmlns:creativeCommons=\"http://backend.userland.com/creativeCommonsRssModule\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<creativeCommons:license>", "<creativeCommons:license xmlns:creativeCommons=\"http://backend.userland.com/creativeCommonsRssModule\">"),
+ new AllowableDifference("<feed xmlns:a=\"http://www.example.com/extension-a\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<a:simple-value>", "<a:simple-value xmlns:a=\"http://www.example.com/extension-a\">"),
+ new AllowableDifference("<a:structured-xml>", "<a:structured-xml xmlns:a=\"http://www.example.com/extension-a\">"),
+ new AllowableDifference("<dc:title>", "<dc:title xmlns:dc=\"http://purl.org/dc/elements/1.1/\">"),
+ new AllowableDifference("<simple-value>", "<simple-value xmlns=\"\">"),
+ new AllowableDifference("<feed xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<feed xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<trackback:about>", "<trackback:about xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\">"),
+ new AllowableDifference("<xhtml:img src=\"http://example.com/image.jpg\">", "<xhtml:img src=\"http://example.com/image.jpg\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">"),
+ new AllowableDifference("<feed xml:base=\"http://example.org\" xmlns=\"http://www.w3.org/2005/Atom\">", "<feed xml:base=\"http://example.org/\" xmlns=\"http://www.w3.org/2005/Atom\">"),
+ new AllowableDifference("<link href=\"http://creativecommons.org/licenses/by-nc/2.5/\" xmlns:lic=\"http://web.resource.org/cc/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" rel=\"http://www.snellspace.com/atom/extensions/proposed/license\" rdf:resource=\"http://creativecommons.org/licenses/by-nc/2.5/\" type=\"text/html\" rdf:type=\"http://web.resource.org/cc/license\">", "<link xmlns:a=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" href=\"http://creativecommons.org/licenses/by-nc/2.5/\" rel=\"http://www.snellspace.com/atom/extensions/proposed/license\" a:resource=\"http://creativecommons.org/licenses/by-nc/2.5/\" type=\"text/html\" a:type=\"http://web.resource.org/cc/license\">"),
+ });
+ }
+
+ private static List<string> GetTestFilesForFeedTest(string dataFile)
+ {
+ List<string> fileList = new List<string>();
+
+ string file;
+ using (StreamReader sr = new StreamReader(dataFile))
+ {
+ while(!string.IsNullOrEmpty(file = sr.ReadLine()))
+ {
+ if (!file.StartsWith("#"))
+ {
+ if (File.Exists(file))
+ {
+ fileList.Add(Path.GetFullPath(file));
+ }
+ else
+ {
+ throw new FileNotFoundException("File not found!",file);
+ }
+ }
+ }
+ }
+ return fileList;
+ }
}
}
<Content Include="$(MsBuildThisFileDirectory)\TestFeeds\*.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Content Include="$(MsBuildThisFileDirectory)\TestFeeds\AtomFeeds\*.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(MsBuildThisFileDirectory)\TestFeeds\atom_feeds.dat">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <id>uuid:43481a10-d881-40d1-adf2-99b438c57e21;id=1</id>
+ <title type="text">SyndicationFeed released for .net Core</title>
+ <updated>2017-10-11T11:25:55Z</updated>
+ <link rel="alternate" href="http://contoso.com/news/path" />
+ <content type="text">A lot of text describing the release of .net core feature</content>
+</entry>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a "rel" which is an absolute IRI produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <link rel="http://www.snellspace.com/atom/extensions/proposed/comments" href="http://www.snellspace.com/wp/wp-commentsatom1.php" />
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with an atom:link element with a rel attribute value of alternate but no atom:content element
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with one entry, which contains an atom:author element only at the entry level
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <author>
+ <name>John Doe</name>
+ </author>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with one entry, both of which contains an atom:author element
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <author>
+ <name>Jane Doe</name>
+ </author>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with one entry, which contains an atom:author element only at the feed level
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:entry elements with the same atom:id and same atom:updated values produces a warning.
+Expect: !MissingElement{parent:feed,element:author}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with one entry, neither of which contains an atom:author element
+Expect: MissingElement{element:author,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:entry,element:scheme}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business" scheme=" http://example.com" a:blah="true" xmlns:a="urn:blah">
+ <a:MyExtension xmlns:a="urn:blah2" />
+ </category>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:entry,element:scheme}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+<category term="business" scheme=" http://example.com" a:blah="true" xmlns:a="urn:blah">
+ <a:MyExtension xmlns:a="urn:blah2" />
+ </category>
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:entry,element:scheme}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+<category term="sci-fi" scheme=" http://example.com" />
+<category term="business" scheme=" http://example.com" />
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: category with a label that appears to contain escaped HTML produces a warning
+Expect: ContainsHTML{element:category}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business" label="<b>business</b>"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: category without a label produces no error
+Expect: !MissingAttribute{attr:label,element:category}
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: category without a scheme produces no error
+Expect: !MissingAttribute{attr:scheme,element:category}
+
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: category with a scheme attribute that is not a valid IRI produces an error
+Expect: InvalidUriChar{element:scheme,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business" scheme="insert value here"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: category with a scheme attribute that is not a valid IRI produces an error
+Expect: InvalidFullLink{element:scheme,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="business" scheme="mine"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: name containing an email address produces a warning
+Expect: ContainsEmail{element:name,parent:author}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe <john@example.com></name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: usage of application/xhtml+xml to describe an xhtml fragment
+Expect: HtmlFragment{element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="application/xhtml+xml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ Some <b>bold</b> text.
+ </div>
+ </content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry contains content that is encoded in Base64 but without a summary
+Expect: MissingSummary{element:entry,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <content type="application/text">U29tZSBtb3JlIHRleHQu</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a type of jpeg and a value that is not valid base64 produces an error
+Expect: NotBase64{element:content,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="image/jpeg">insert image here</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a type of jpeg and a value that is valid base64 produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="image/jpeg">
+ /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a
+ HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy
+ MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABYAGoDAREA
+ AhEBAxEB/8QAGwAAAgIDAQAAAAAAAAAAAAAAAAIBAwQGBwX/xAA4EAABAwIDAwgJAwUAAAAAAAAB
+ AAIDBBEFEmEUIaEGBzFBUYGR0RMiM1RxkpPh8DJTwSNDRFJi/8QAGgEBAQEBAQEBAAAAAAAAAAAA
+ AAECAwUEBv/EACIRAQACAgEEAwEBAAAAAAAAAAABAgMREwQSIVEFIzFBMv/aAAwDAQACEQMRAD8A
+ 7+gi6AzIDMgMyAzIDMgMyAzIDMgMyAzIJugECkoEJOqoi51TQLnVNAudU0C51TQLnVNAudU0C51T
+ QLnVNAudU0JBKBgoHQI5BUe5URfUcFQpe0dLgPBNCs1dM02M8YOrgtxjvP5AjbaX3iL5wnFf0m4G
+ 20vvEXzhOK/o3A22l94i+cK8V/RuEitpT/kRfMFOK/o3CwSMcLtc0/AhYmJjwprjtHBBI/OhQWNU
+ FiBHIKzfXiqMSvro8Po5Kmd+WONpJJJXTFjtktFapM68uGY3zj4lyjx+LC8NnNJSSSZDIOm3WV7+
+ HpceLxEblym222UlFgrIWskbLUvA3yTTOLnHxUyRn348ETDJFFgnug+o/wA1z+/2u4NseCe6j6j/
+ ADU+/wBm4QaLBLb6UfUf5p9/s3CuSjwLIQKYsuP1NleCO+61WM/s8NKquV+J8i+UTYIa2Wrw6QB7
+ WzOzOaL2sSu98NMkRGSuk3Mfjs3JvlBTcocMjrKZ25w9ZtzcFeH1XTzgv2y6VmJe2L68V8rSxt1A
+ 9kCOQVO7uCo5lzuYlJBgjKSJ3tj61l7fxWKJmbuWSXIcHwh75GyAEOvcEL3MWKKx3S5zLdKajqwB
+ eeTxWrXommcykqQPbv8AFcZyUXRxR1P7z/FTkoaK6kqh/ef4qxkoaYs1HV23TvXSL0TTU8awiWRx
+ kkLnut0net3pW8bPxtnM/Xy0mJz0Dj/TcLgdhXk/IYd4Nz+w6Uny7gw3F93BfnHZc1ZFiBHIKXk6
+ 8VqBzLnQo3VEED7EgG3Wv0Hw1o81ccjWcCogI23C9bPfthiIbTBSCw3LzL5pb0ym0Y7FwtmXR9iH
+ Ys8y6Q6i0VjMmmNLSCx3LtXLJp4GLUTTE7d1L0OnyTLEwTm9oCzlC6UDc0X3Ll8pMVwTHtafrs7L
+ 26+K/KS7r2rIdQK5BS8A9nBaGtcpMOixGikgksL9DgBdp6j0r7+jzTivFoYtG4c/poZ8LnMNUzKA
+ fVeP0u71+hteueu6uWtNjpamIgG4Xm5cdoaiXpx1FPbeQvjtSzW4Wiopv9gs9l18EkqacdBCtcdj
+ bz6mphsfWC+nHjsky1zEJHVb/QU0ZlkPU3+V6mKIxx3WlzltHJLBRhkJMhDp5N7yLW+AXkdf1PLb
+ UfjpSNN2jbuH2Xky6L2rIsUCOQVOuVoYFdDnZuvxXXHKS16en3kObdvYR9l9tL+mdMbYoAbiFg+D
+ fsu3Lef6moNs0YHsm+CzyW9mgII/2x4J329mhs8ZG+IeCd9va6K6jgI3wsPxCsZbx/U0tgp2t9WO
+ MMH/ACLfwsXyTP8AqV1EPew+BzbE34r48ttrD1m3H4V87S1t1A6gRyCs2VFb2NeLbvzvWolHmVFG
+ HE2A/O9dqX0mmG6gP5bzXSMppGwnTh5q8pobDoOHmnKDYTpw805TQ2E6cPNOU0yqeiAPQOHmudsm
+ zT1Iowxthbh5rhM7VaLdqirGrIsQI5BWQT2qgsdUClt+lXYgxA9qbRHohqrtR6Iap3A9CNU7gehG
+ qbDBgHRdTYbKe0qAAOqCxqgdBBF0ClvwQRlCoLBAZQgMoQFggMoQGUIDKEBlHYgMqgYCyBkH/9k=
+ </content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with an atom:content element but no atom:link element with a rel attribute value of alternate
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content>Danger, Will Robinson!</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with no type attribute and a value containing escaped html produces a warning
+Expect: ContainsUndeclaredHTML{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content>Some <b>bold</b> text.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a type of plain and children elements produces an error
+Expect: UndefinedElement{parent:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="text/plain">Some <b>bold</b> text.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with an atom:content that has a src attribute but with no summary
+Expect: MissingSummary{element:entry,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <content src="http://example.org/2003/12/13/atom03"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and no type attribute produces a warning
+Expect: !InvalidMIMEType
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and no type attribute produces a warning
+Expect: MissingTypeAttr{element:content,attr:type,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute that is a relative IRI reference produce no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="2003/12/12/atom03.pdf" type="application/pdf"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and a type attribute of html produces an error
+Expect: InvalidValue{element:content,attr:type,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03" type="html"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and a type attribute of text/html produces no error
+Expect: !HtmlFragment{element:content,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03" type="text/html"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and a type attribute of text produces an error
+Expect: InvalidValue{element:content,attr:type,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03" type="text"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a src attribute and a type attribute of xhtml produces an error
+Expect: InvalidValue{element:content,attr:type,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03" type="xhtml"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Remote content should produce no NotBlank warning
+Expect: !NotBlank
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: usage of text/html to describe an html fragment
+Expect: HtmlFragment{element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="text/html">Some <b>bold</b> text.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xhtml content value containing only escaped html produces a warning
+Expect: NotInline{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Some <b>bold</b> text.</div></content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xhtml content with elements and escaped text
+Expect: !NotInline{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><b>Example:</b> Some <b>bold</b> text.</div></content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a type of xhtml and an immediate child elements other than xhtml:div produces an error
+Expect: MissingXhtmlDiv{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml"><span xmlns="http://www.w3.org/1999/xhtml">text</span></content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xhtml content value containing only escaped non-html produces no warning
+Expect: !NotInline{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Some <x>bold</x> text.</div></content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a "type" of "xhtml" and child text nodes produces an error
+Expect: MissingXhtmlDiv{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml">text & more</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:entry elements with the same atom:id value produces a warning.
+Expect: DuplicateEntries
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Different text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: RSS 2.0 style email addresses
+Expect: InvalidAddrSpec{element:email,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <email>me@example.com (Jane Doe)</email>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: RFC 2822 "name-addr" style email address
+Expect: InvalidAddrSpec{element:email,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <email>Jane Doe <jane@example.com></email>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: email with a plus sign
+Expect: ValidContact{element:email,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <email>jane+doe@example.com</email>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: an entry with an empty atom:content element produces a warning
+Expect: NotBlank{parent:entry,element:content}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title type="text">Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title type="text">Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="text">Some text.</summary>
+ <content/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: an entry with an empty atom:title produces a warning
+Expect: NotBlank{parent:entry,element:title}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title/>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<feed xmlns="http://www.w3.org/2005/Atom">
+<title type="text"></title>
+<id>16ba9aff-eb42-4907-a86e-dcdc6068b20a</id>
+<updated>2007-04-11T20:04:16Z</updated>
+
+<author />
+
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: escaped html marked at text
+Expect: ContainsUndeclaredHTML{element:summary}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="text">Some&nbsp;escaped&nbsp;html</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:title with html content
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title type="html">
+ Less: <em> &lt; </em>
+ </title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:title with text content
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title type="text">
+ Less: <
+ </title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:summary with xhtml content
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ This is <b>XHTML</b> content.
+ </div>
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:summary with xhtml content
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="xhtml">
+ <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ This is <xhtml:b>XHTML</xhtml:b> content.
+ </xhtml:div>
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:summary with xhtml content
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry xmlns:xh="http://www.w3.org/1999/xhtml">
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="xhtml">
+ <xh:div>
+ This is <xh:b>XHTML</xh:b> content.
+ </xh:div>
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Unknown extension elements in feed and entry should not affect validity
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:a="http://www.example.com/extension-a"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <a:simple-value>Test</a:simple-value>
+ <a:structured-xml><dc:title>A structured extension element</dc:title></a:structured-xml>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <a:simple-value>Test</a:simple-value>
+ <a:structured-xml><dc:title>A structured extension element</dc:title></a:structured-xml>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Description: No errors should be produced by the extensive feed
+ Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">dive into mark</title>
+ <subtitle type="html">
+ A <em>lot</em> of effort
+ went into making this effortless
+ </subtitle>
+ <updated>2005-07-11T12:29:29Z</updated>
+ <id>tag:example.org,2003:3</id>
+ <link rel="alternate" type="text/html"
+ hreflang="en" href="http://example.org/"/>
+ <link rel="self" type="application/atom+xml"
+ href="http://example.org/feed.atom"/>
+ <rights>Copyright (c) 2003, Mark Pilgrim</rights>
+ <generator uri="http://www.example.com/" version="1.0">
+ Example Toolkit
+ </generator>
+ <entry>
+ <title>Atom draft-07 snapshot</title>
+ <link rel="alternate" type="text/html"
+ href="http://example.org/2005/04/02/atom"/>
+ <link rel="enclosure" type="audio/mpeg" length="1337"
+ href="http://example.org/audio/ph34r_my_podcast.mp3"/>
+ <id>tag:example.org,2003:3.2397</id>
+ <updated>2005-07-11T12:29:29Z</updated>
+ <published>2003-12-13T08:29:29-04:00</published>
+ <author>
+ <name>Mark Pilgrim</name>
+ <uri>http://example.org/</uri>
+ <email>f8dy@example.com</email>
+ </author>
+ <contributor>
+ <name>Sam Ruby</name>
+ </contributor>
+ <contributor>
+ <name>Joe Gregorio</name>
+ </contributor>
+ <content type="xhtml" xml:lang="en"
+ xml:base="http://diveintomark.org/">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <p><i>[Update: The Atom draft is finished.]</i></p>
+ </div>
+ </content>
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Description: No errors should be produced by the extensive feed
+ Expect: !Warning
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">dive into mark</title>
+ <subtitle type="html">
+ A <em>lot</em> of effort
+ went into making this effortless
+ </subtitle>
+ <updated>2005-07-11T12:29:29Z</updated>
+ <id>tag:example.org,2003:3</id>
+ <link rel="alternate" type="text/html"
+ hreflang="en" href="http://example.org/"/>
+ <link rel="self" type="application/atom+xml"
+ href="http://www.feedvalidator.org/testcases/atom/1.1/extensive-nowarn.xml"/>
+ <rights>Copyright (c) 2003, Mark Pilgrim</rights>
+ <generator uri="http://www.example.com/" version="1.0">
+ Example Toolkit
+ </generator>
+ <entry>
+ <title>Atom draft-07 snapshot</title>
+ <link rel="alternate" type="text/html"
+ href="http://example.org/2005/04/02/atom"/>
+ <link rel="enclosure" type="audio/mpeg" length="1337"
+ href="http://example.org/audio/ph34r_my_podcast.mp3"/>
+ <id>tag:example.org,2003:3.2397</id>
+ <updated>2005-07-11T12:29:29Z</updated>
+ <published>2003-12-13T08:29:29-04:00</published>
+ <author>
+ <name>Mark Pilgrim</name>
+ <uri>http://example.org/</uri>
+ <email>f8dy@example.com</email>
+ </author>
+ <contributor>
+ <name>Sam Ruby</name>
+ </contributor>
+ <contributor>
+ <name>Joe Gregorio</name>
+ </contributor>
+ <content type="xhtml" xml:lang="en"
+ xml:base="http://diveintomark.org/">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <p><i>[Update: The Atom draft is finished.]</i></p>
+ </div>
+ </content>
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: generator with text that appears to contain escaped HTML produces a warning
+Expect: ContainsHTML{element:generator,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <generator uri="/generator"><b>The</b> generator</generator>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: generator without text produces a warning
+Expect: NotBlank{element:generator,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <generator uri="/generator"/>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: icon that is a relative IRI reference produce no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <generator uri='misc/Colophon'>Generated from XML source code using Perl, Expat, XML::Parser, Emacs, Mysql, and ImageMagick. Industrial strength technology, baby.</generator>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: icon with content that is not a valid IRI reference produces an error
+Expect: InvalidLink{element:icon,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <icon>insert uri here</icon>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: icon that is a relative IRI reference produce no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <icon>favicon.ico</icon>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with dot-segments in path produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org/./id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with an empty fragment identifier produces no warning
+Expect: !NonCanonicalURI
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org/id/1234#</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with an empty path for schemes like http produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with an empty query produces no warning
+Expect: !NonCanonicalURI
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org/id/1234?</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with an explicit authority equivalent to the default produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://:@example.org/id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id whith an explicitly specified default port produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org:80/id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with a host in uppercase characters produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://Example.org/id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id which uses a non-IANA registered scheme produces a warning
+Expect: SchemeNotIANARegistered{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>doi:10.1038/nature05582</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id which is not an IRI produces an error
+Expect: InvalidLink{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>insert id here</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with percent-encoding using lowercase characters produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org/id/1234?q=%5c</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with percent-encoding unnecessarily produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>http://example.org/%69%64/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id which is a relative IRI produces an error
+Expect: InvalidFullLink{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>/id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: id with a scheme in uppercase characters produces a warning
+Expect: NonCanonicalURI{element:id,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>Http://example.org/id/1234</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Valid Tag URIs, according to RFC 4151, should not produce errors
+Expect: !InvalidTAG
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>tag:example.com,2000:</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/1"/>
+ <id>tag:example.com,2000:#anchor</id>
+ <updated>2005-12-18T13:32:18Z</updated>
+ </entry>
+
+ <entry>
+ <title>Atom-Powered Robots Test Empty Fragments</title>
+ <link href="http://example.org/2"/>
+ <id>tag:example.com,2000:#</id>
+ <updated>2005-12-18T13:32:33Z</updated>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: The order of attributes within a start-tag is not significant.
+Expect: DuplicateAtomLink{parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+
+ <link href="http://example.org/" rel="alternate"/>
+ <link rel="alternate" href="http://example.com/"/>
+
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whether characters are represented by character references or not is not significant.
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+
+ <updated>2003-12-13T18:30:02Z</updated>
+
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: White space within start-tags (other than significant white space in attribute values) and end-tags is not significant.
+Expect: DuplicateAtomLink{parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <link
+ href="http://example.com"
+ />
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Empty title element
+Expect: NotBlank{element:title,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title />
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Empty title element
+Expect: NotBlank{element:title,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title/>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: The kind of quotation marks (single or double) used to quote attribute values is not significant.
+Expect: !Error
+-->
+
+<feed xmlns='http://www.w3.org/2005/Atom'>
+
+ <title>Example Feed</title>
+ <link href='http://example.org/'/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href='http://example.org/2003/12/13/atom03'/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: contributor with an atom:email that is not valid
+Expect: InvalidAddrSpec{element:email,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <email>enter email address here</email>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: contributor with an atom:uri that is not a valid IRI reference
+Expect: InvalidLink{element:uri,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <uri>enter homepage here</uri>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xml base with an invalid iri
+Expect: InvalidUriChar{element:xml:base}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:base="invalid iri">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: invalid xml:lang an error
+Expect: InvalidLanguage{element:xml:lang}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en_us">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<!--
+ Description: summary says it's html, but isn't
+ Expect: NotHtml{parent:entry,element:summary}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="html">
+ <a
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: creativeCommons:license element
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <creativeCommons:license>http://creativecommons.org/licenses/by/2.0/</creativeCommons:license>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Foreign markup as a child of an atom:link element
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <link rel="http://www.snellspace.com/atom/extensions/proposed/license"
+ type="text/html"
+ href="http://creativecommons.org/licenses/by-nc/2.5/"
+ rdf:resource="http://creativecommons.org/licenses/by-nc/2.5/"
+ rdf:type="http://web.resource.org/cc/license"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:lic="http://web.resource.org/cc/">
+ <lic:permits rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <lic:permits rdf:resource="http://web.resource.org/cc/Distribution" />
+ <lic:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <lic:requires rdf:resource="http://web.resource.org/cc/Notice" />
+ <lic:requires rdf:resource="http://web.resource.org/cc/Attribution" />
+ <lic:requires rdf:resource="http://web.resource.org/cc/Noncommercial" />
+ <lic:requires rdf:resource="http://web.resource.org/cc/Metadata"/> <!-- existing metadata must be preserved -->
+ <lic:requires rdf:resource="http://www.resource.org/cc/NoAdvertisements"/> <!-- forbids advertisements from being added to the content -->
+ </link>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with an atom:link with a rel attribute value specifying an unrecognized fully qualified IRI
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <link rel="http://xmlns.com/foaf/0.1/" href="http://example.org/foaf"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a href link-href-invalid.xml link-no-href.xml
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a hreflang attribute that is not a language tag produces an error
+Expect: InvalidLanguage{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03" hreflang="insert language here"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with an atom:link with a rel attribute value specifying an unrecognized fully qualified IRI
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <link rel="http://xmlns.com/foaf/0.1/" href="http://example.org/foaf"/>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a rel with iana org
+Expect: !MissingSelf
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <id>urn:linkreltest:feed</id>
+ <title>Testing Link Rels</title>
+ <link rel="http://www.iana.org/assignments/relation/self"
+ href="http://www.snellspace.com/public/linkreltest.xml" />
+ <link rel="http://www.iana.org/assignments/relation/alternate"
+ href="http://www.snellspace.com/public/linkreltest.xml" />
+ <author><name>James</name></author>
+ <updated>2006-04-25T12:12:12Z</updated>
+ <entry>
+ <id>urn:linkreltest:1</id>
+ <title>Does your reader support http://www.iana.org/assignments/relation/alternate properly? </title>
+ <updated>2006-04-25T12:12:12Z</updated>
+ <link rel="http://www.iana.org/assignments/relation/alternate"
+ href="http://www.snellspace.com/public/alternate" />
+ <content>This entry uses link/@rel="http://www.iana.org/assignments/relation/alternate".</content>
+ </entry>
+ <entry>
+ <id>urn:linkreltest:2</id>
+ <title>How does your reader handle uppercase variances of standard rel values?</title>
+ <updated>2006-04-25T12:12:13Z</updated>
+ <link rel="ALTERNATE"
+ href="http://www.snellspace.com/public/alternate2" />
+ <link rel="alternate"
+ href="http://www.snellspace.com/public/alternate" />
+ <content>This entry uses an uppercase "ALTERNATE" and a lowercase "alternate", your reader should show the lowercase link to http://www.snellspace.com/public/alternate.</content>
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a rel which matches isegment-nz-nc produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link rel="alternate" href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a rel which is a relative IRI but not a isegment-nz-nc produces an error
+Expect: UnregisteredAtomLinkRel{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link rel="/foo" href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with two atom:link elements with a rel attribute value of alternate that has the differing types
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03.pdf" rel="alternate" type="application/pdf"/>
+ <link href="http://example.org/2003/12/13/atom03.html" rel="alternate" type="text/html"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with two atom:link elements with a rel attribute value of alternate that has the same type but differing hreflang attribute values
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03/es" rel="alternate" type="text/html" hreflang="es-es"/>
+ <link href="http://example.org/2003/12/13/atom03/en" rel="alternate" type="text/html" hreflang="en-us"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with two atom:link elements with a rel attribute value of alternate that has the same type and hreflang attribute values
+Expect: DuplicateAtomLink{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom02" rel="alternate" type="text/html" hreflang="en-us"/>
+ <link href="http://example.org/2003/12/13/atom03" rel="alternate" type="text/html" hreflang="en-us"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with two atom:link elements with a rel attribute value of alternate that has the same type and no hreflang attribute values
+Expect: DuplicateAtomLink{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom02" rel="alternate" type="text/html"/>
+ <link href="http://example.org/2003/12/13/atom03" rel="alternate" type="text/html"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a title attribute which appears to contain HTML produces a warning
+Expect: BadCharacters{element:title,parent:link}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"
+ title="This is a £\93test.\94"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a title attribute which appears to contain HTML produces a warning
+Expect: ContainsHTML{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"
+ title="very, <b>very</b>, scary indeed"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a type attribute which does not match the syntax of a MIME media type produces an error
+Expect: InvalidMIMEType{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link type="insert type here" href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link type with parameters produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link type="text/html; charset=utf-8" href="http://example.org/2003/12/13/atom-robots.html"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: logo that is a relative IRI reference produce no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <logo>atomlogo.png</logo>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with zero atom:id elements produces a warning
+Expect: MissingSourceElement{element:id,parent:source}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <updated>2003-12-13T17:46:27Z</updated>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed without an atom:link element with a rel attribute value of self produces a warning
+Expect: MissingSelf{element:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with zero atom:title elements produces a warning
+Expect: MissingSourceElement{element:title,parent:source}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: source with zero atom:updated elements produces a warning
+Expect: MissingSourceElement{element:updated,parent:source}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<!--
+ Description: Summary with a type of xhtml needs to include an xhtml:div
+ Expect: MissingXhtmlDiv{parent:entry,element:summary}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ So I was reading <xhtml:a href="http://example.com/">example.com</xhtml:a> the other day, it's really interesting.
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Example atom:summary with xhtml content
+Expect: MissingNamespace{element:b}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ This is <b xmlns="">XHTML</b> content.
+ </div>
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<!--
+ Description: can have multiple enclosures per entry
+ Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">
+ <title>Enclosure Test</title>
+ <link href="http://www.cadenhead.org/workbench/"/>
+ <id>http://www.cadenhead.org/workbench/</id>
+ <subtitle>Testing multiple enclosure elements</subtitle>
+ <generator>Wordzilla/0.101</generator>
+ <updated>2004-12-27T11:12:01-05:00</updated>
+ <author>
+ <name>Rogers Cadenhead</name>
+ </author>
+ <entry>
+ <title>Kirk Cameron</title>
+ <link href="http://www.cadenhead.org/workbench/entry/2004/12/27#2424"/>
+ <summary>Here's a two-enclosure test</summary>
+ <updated>2004-12-27T11:12:01-05:00</updated>
+ <id>tag:cadenhead.org,2004-09-30:test.2423</id>
+ <link rel="enclosure" href="http://www.cadenhead.org/workbench/gems/kirk-cameron-you-are-a-blasphemer.mp3" length="3762" type="audio/mpeg"/>
+ <link rel="enclosure" href="http://www.cadenhead.org/workbench/gems/kirk-cameron-you-only-love-god.mp3" length="19331" type="audio/mpeg"/>
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two one atom:link elements with a rel attribute value of "alternate", but with different type and hreflang attribute values produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <link href="http://example.org/" hreflang="en-us"/>
+ <link href="http://example.es/" hreflang="es-es"/>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two one atom:link elements with a rel attribute value of alternate, but with different type and hreflang attribute value
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/" hreflang="en-us"/>
+ <link href="http://example.es/" hreflang="es-es"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two atom:link elements with a rel attribute value of "alternate" with the same type and hreflang attribute value produces an error
+Expect: DuplicateAtomLink{parent:source}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <link href="http://example.org/front-page.html" rel="alternate" type="text/html" hreflang="en-us"/>
+ <link href="http://example.org/second-page.html" rel="alternate" type="text/html" hreflang="en-us"/>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:link elements with a rel attribute value of alternate and with the same type and hreflang attribute value
+Expect: DuplicateAtomLink{parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/front-page.html" rel="alternate" type="text/html" hreflang="en-us"/>
+ <link href="http://example.org/second-page.html" rel="alternate" type="text/html" hreflang="en-us"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom02"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two atom:author elements produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <author>
+ <name>Jane Doe</name>
+ </author>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:author elements
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <author>
+ <name>Jane Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with multiple atom:category elements
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="technology"/>
+ <category term="business"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two atom:category elements produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <category term="technology"/>
+ <category term="business"/>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:category elements
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <category term="technology"/>
+ <category term="business"/>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with multiple atom:contributor elements
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+
+ <contributor>
+ <name>John Smith</name>
+ </contributor>
+ <contributor>
+ <name>Jane Doe</name>
+ </contributor>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two atom:contributor elements produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <contributor>
+ <name>John Smith</name>
+ </contributor>
+ <contributor>
+ <name>Jane Doe</name>
+ </contributor>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:contributor elements
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>John Smith</name>
+ </contributor>
+ <contributor>
+ <name>Jane Doe</name>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a source with two atom:icon elements produces an error
+Expect: DuplicateElement{element:icon,parent:source}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <source>
+ <title>Source of all knowledge</title>
+ <id>urn:uuid:28213c50-f84c-11d9-8cd6-0800200c9a66</id>
+ <updated>2003-12-13T17:46:27Z</updated>
+ <icon>/big.icon</icon>
+ <icon>/small.icon</icon>
+ </source>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:icon elements
+Expect: DuplicateElement{element:icon,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <icon>/big.icon</icon>
+ <icon>/small.icon</icon>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with two atom:link elements with a rel attribute value of related and with the same type and hreflang attribute value
+Expect: !DuplicateAtomLink{parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/front-page.html" rel="related" type="text/html" hreflang="en-us"/>
+ <link href="http://example.org/second-page.html" rel="related" type="text/html" hreflang="en-us"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom02"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with neither an atom:link element with a rel attribute value of alternate nor an atom:content element
+Expect: MissingContentOrAlternate{element:entry,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: an entry with no atom:content or atom:summary produces a warning
+Expect: MissingTextualContent{element:entry,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: contributor without an atom:name produces an error
+Expect: MissingElement{element:name,parent:contributor}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <email>jane@example.com</email>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Mising Namespace on feed element
+Expect: !Error
+-->
+
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
+
+ <atom:title>Example Feed</atom:title>
+ <atom:link href="http://example.org/"/>
+ <atom:updated>2003-12-13T18:30:02Z</atom:updated>
+ <atom:author>
+ <atom:name>John Doe</atom:name>
+ </atom:author>
+ <atom:id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</atom:id>
+
+ <atom:entry>
+ <atom:title>Atom-Powered Robots Run Amok</atom:title>
+ <atom:link href="http://example.org/2003/12/13/atom03"/>
+ <atom:id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</atom:id>
+ <atom:updated>2003-12-13T18:30:02Z</atom:updated>
+ <atom:summary>Some text.</atom:summary>
+ </atom:entry>
+
+</atom:feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: RDF extensions to Atom
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:foaf="http://xmlns.com/foaf/0.1/">
+ <title>Example Feed</title>
+ <link href="http://example.org/" rdf:resource="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <dc:description>A feed whose description here tries to be
+ legal Atom 1.0 but also use some foreign markup to have it
+ also count as legal RDF. Are the rdf:resource attributes OK?</dc:description>
+ <author rdf:parseType="Resource">
+ <name>John Doe</name>
+ <foaf:workplaceHomepage
+rdf:resource="http://DoeCorp.example.com/"></foaf:workplaceHomepage>
+ <!-- we could use this to build a Planet DoeCorp -->
+ <foaf:homepage rdf:resource="http://jondoe.example.org/"></foaf:homepage>
+ <foaf:weblog rdf:resource="http://jondoe.example.org/blog/"></foaf:weblog>
+ <!-- overlap with atom person constructs here -->
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <entry rdf:parseType="Resource">
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"
+ rdf:resource="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <foaf:primaryTopic rdf:parseType="Resource">
+ <foaf:isPrimaryTopicOf rdf:resource="http://en.wikipedia.org/wiki/Atom_(standard)"></foaf:isPrimaryTopicOf>
+ </foaf:primaryTopic>
+ <!-- ie. this entry has as a primary topic the resource that
+ is the primary topic of that document on wikipedia -->
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: ValidXMLBase
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://example.org">
+
+ <title>Example Feed</title>
+ <link href="index.html"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="?foo=1:2"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with two atom:link elements with a rel attribute value of related that has the same type and hreflang attribute values
+Expect: !DuplicateAtomLink{element:link,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom02" rel="related" type="text/html" hreflang="en-us"/>
+ <link href="http://example.org/2003/12/13/atom03" rel="related" type="text/html" hreflang="en-us"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: contributor with an atom:uri that is a relative IRI reference
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <contributor>
+ <name>Jane Doe</name>
+ <uri>~jane/</uri>
+ </contributor>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: rights with a type of text but appears to include escaped html produces a warning
+Expect: ContainsUndeclaredHTML{element:rights,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <rights type="text">Copyright &copy; 2005</rights>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Rights with a type of xhtml needs to include an xhtml:div
+Expect: MissingXhtmlDiv{element:rights,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <rights type="xhtml">all rights reserved</rights>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Self-rel referencing a non-Atom representation
+Expect: SelfNotAtom
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link rel="self" type="text/html" href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a subtitle that is blank produces a warning
+Expect: NotBlank{element:subtitle,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <subtitle/>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry contains content that is encoded in Base64 with a summary
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="application/text">U29tZSBtb3JlIHRleHQu</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: entry with an atom:summary and an atom:content that has a src attribute
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src="http://example.org/2003/12/13/atom03.pdf" type="application/pdf"/>
+ </entry>
+
+</feed>
--- /dev/null
+<!--
+ Description: Summary with a type of text but appears to include escaped html produces a warning
+ Expect: ContainsUndeclaredHTML{parent:entry,element:summary}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>
+ So I was reading <a href="http://example.com/">example.com</a> the other day, it's really interesting.
+ </summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a subtitle that is blank produces a warning
+Expect: NotBlank{element:title,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title/>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Valid trackback:about elements should be permitted on entries
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <trackback:about>http://www.example.net/article/01</trackback:about>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Valid trackback:ping elements should be permitted on entries
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <trackback:ping>http://www.example.com/trackback.cgi?id=1225c695-cfb8-4ebb-aaaa-80da344efa6a</trackback:ping>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: trackback:ping is only defined for feed entries
+Expect: UndefinedElement{parent:feed,element:trackback:ping}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <trackback:ping>http://www.example.com/trackback.cgi</trackback:ping>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with type of html produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="html">Some content.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a valid composite mime type produces an error
+Expect: InvalidMIMEType{element:content,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="multipart/alternative">Some content.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with a valid non-composite mime type produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="text/html">
+ <html>
+ <head>
+ <title>Some title.</title>
+ </head>
+ <body>
+ Some content.
+ </body>
+ </html>
+ </content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with type of text produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="text">Some content.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with type of xhtml produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Some content.</div></content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: content with type of xml produces an error
+Expect: InvalidMIMEType{element:content,parent:entry}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content type="xml">Some content.</content>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Unknown extension elements without a namespace get a warning
+Expect: UndeterminableVocabulary{element:simple-value}
+-->
+
+<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
+
+ <atom:title>Example Feed</atom:title>
+ <atom:link href="http://example.org/"/>
+ <atom:updated>2003-12-13T18:30:02Z</atom:updated>
+ <atom:author>
+ <atom:name>John Doe</atom:name>
+ </atom:author>
+ <atom:id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</atom:id>
+ <simple-value>Test</simple-value>
+
+ <atom:entry>
+ <atom:title>Atom-Powered Robots Run Amok</atom:title>
+ <atom:link href="http://example.org/2003/12/13/atom03"/>
+ <atom:id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</atom:id>
+ <atom:updated>2003-12-13T18:30:02Z</atom:updated>
+ <atom:summary>Some text.</atom:summary>
+ </atom:entry>
+
+</atom:feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Unknown extension elements without a namespace get a warning
+Expect: UndeterminableVocabulary{element:simple-value}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <simple-value xmlns="">Test </simple-value>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Extension elements without a namespace in unknown namespace produce no warning
+Expect: !UndeterminableVocabulary
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <value xmlns="http://www.example.com/value">Test <data xmlns=""></data> </value>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: link with a "rel" which matches isegment-nz-nc but is not in the IANA registry produces an error
+Expect: UnregisteredAtomLinkRel{value:service.post,element:link,parent:feed}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <link rel="service.post" href="http://example.org/atom.cgi"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Updated example from the spec
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02+01:00</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xml base with an valid iri
+Expect: !InvalidIRI{element:xml:base}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://www.詹姆斯.com/feed">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnexpectedWhitespace{parent:author,element:uri}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ <uri>
+ http://example.com/
+ </uri>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:entry,element:scheme}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <category term="sci-fi" scheme=" http://example.com" />
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:entry,element:content,attr:src}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <content src=" http://www.example.com/doc.pdf" type="application/pdf"/>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnexpectedWhitespace{parent:entry,element:id}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>
+ urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a
+ </id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in dates
+Expect: UnexpectedWhitespace{parent:entry,element:published}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <published>
+ 2003-12-13T12:17:23Z
+ </published>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in dates
+Expect: UnexpectedWhitespace{parent:entry,element:updated}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>
+ 2003-12-13T18:30:02Z
+ </updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnexpectedWhitespace{parent:feed,element:icon}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <icon>
+ http://example.com/icon.jpg
+ </icon>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnexpectedWhitespace{parent:feed,element:id}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>
+ urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6
+ </id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnexpectedWhitespace{parent:feed,element:logo}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <logo>
+ http://www.example.com/logo.gif
+ </logo>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in dates
+Expect: UnexpectedWhitespace{parent:feed,element:updated}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>
+ 2003-12-13T18:30:02Z
+ </updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidUriChar{parent:feed,element:generator,attr:uri}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/" rel="alternate"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <generator uri="http://www.example.com/ " version="1.0">
+ Example Toolkit
+ </generator>
+
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: InvalidLink{parent:feed,element:link}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href=" http://example.org/ "/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Whitespace is not permitted in uris
+Expect: UnregisteredAtomLinkRel{parent:feed,element:link}
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/" rel=" alternate "/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: XHTML extensions to Atom
+Expect: MisplacedXHTMLContent
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xmlns:xhtml="http://www.w3.org/1999/xhtml">
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ <xhtml:img src="http://example.com/image.jpg"></xhtml:img>
+ </entry>
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Document XML base != Element XML base == href
+Expect: SameDocumentReference
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://example.org/">
+
+ <title>Example Feed</title>
+ <link href="."/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: Document XML base != Element XML base != href
+Expect: !SameDocumentReference
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom"
+ xml:base="http://www.feedvalidator.org/testcases/atom/2/">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <link rel="self" href="xml-base-elem-ne-doc.xml"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: ValidXMLBase
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://example.org">
+
+ <title>Example Feed</title>
+ <link href="index.html"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: blank xml:lang produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: xml:lang produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+ </entry>
+
+</feed>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: a feed with zero entries produces no error
+Expect: !Error
+-->
+
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+ <title>Example Feed</title>
+ <link href="http://example.org/"/>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ </author>
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+
+</feed>
--- /dev/null
+absolute_rel.xml
+alternate-no-content.xml
+author-at-entry-only.xml
+author-at-feed-and-entry.xml
+author-at-feed-only.xml
+authorless-with-no-entries.xml
+authorless-with-one-entry.xml
+category-label-escaped-html.xml
+category-no-label.xml
+category-no-scheme.xml
+category-scheme-invalid-iri.xml
+category-scheme-rel-iri.xml
+###category-entry-ext.xml The method or operation is not implemented.
+###category-feed-ext.xml The method or operation is not implemented.
+category-feed.xml
+contains-email.xml
+content-application-xthml.xml
+content-base64-no-summary.xml
+content-jpeg-invalid-base64.xml
+content-jpeg-valid-base64.xml
+content-no-alternate.xml
+content-no-type-escaped-html.xml
+content-plain-with-children.xml
+content-src-no-summary.xml
+content-src-no-type-no-error.xml
+content-src-no-type.xml
+content-src-relative-ref.xml
+content-src-type-html.xml
+content-src-type-text-html.xml
+content-src-type-text.xml
+content-src-type-xhtml.xml
+content-src.xml
+content-text-html.xml
+content-xhtml-escaped.xml
+content-xhtml-mixed.xml
+content-xhtml-no-xhtml-div.xml
+content-xhtml-notmarkup.xml
+content-xhtml-text-children.xml
+duplicate-entries.xml
+email-rss20-style.xml
+email-with-name.xml
+email-with-plus.xml
+empty-content.xml
+empty-title.xml
+empty_author.xml
+escaped_text.xml
+example_html_title.xml
+example_text_title.xml
+example_xhtml_summary1.xml
+example_xhtml_summary2.xml
+example_xhtml_summary3.xml
+###extension-unknown-noerror.xml The method or operation is not implemented.
+extensive-noerror.xml
+extensive-nowarn.xml
+generator-escaped-html.xml
+generator-no-text.xml
+generator_relative_ref.xml
+###icon_invalid_uri.xml This operation is not supported for a relative URI.
+###icon_relative_ref.xml
+id-dot-segments.xml
+id-empty-fragment-id.xml
+id-empty-path.xml
+id-empty-query.xml
+id-explicit-authority.xml
+id-explicit-default-port.xml
+id-host-uppercase.xml
+id-noniana.xml
+id-not-uri.xml
+id-percent-encoded-lower.xml
+id-percent-encoded.xml
+id-relative-uri.xml
+id-uppercase-scheme.xml
+id-valid-tag-uris.xml
+infoset-attr-order.xml
+infoset-char-ref.xml
+infoset-element-whitespace.xml
+infoset-empty1.xml
+infoset-empty2.xml
+infoset-quote-single.xml
+invalid-email.xml
+invalid-uri.xml
+invalid-xml-base.xml
+###invalid-xml-lang.xml The method or operation is not implemented.
+invalid_html.xml
+###license-noerror.xml The method or operation is not implemented.
+###link-extensions.xml Generated result file is different
+link-full-uri.xml
+link-href-relative.xml
+link-hreflang-invalid-language.xml
+link-rel-full.xml
+link-rel-iana.xml
+link-rel-isegment-nz-nc.xml
+link-rel-relative.xml
+link-same-rel-different-types.xml
+link-same-rel-type-different-hreflang.xml
+link-same-rel-type-hreflang.xml
+link-same-rel-type-no-hreflang.xml
+link-title-with-badchars.xml
+link-title-with-html.xml
+link-type-invalid-mime.xml
+link-type-parameters.xml
+logo_relative_ref.xml
+missing-id-source.xml
+missing-self.xml
+missing-title-source.xml
+missing-updated-source.xml
+missing_xhtml_div.xml
+missing_xhtml_ns.xml
+###multi-enclosure-test.xml The method or operation is not implemented.
+multiple-alternates-differing-source.xml
+multiple-alternates-differing.xml
+multiple-alternates-matching-source.xml
+multiple-alternates-matching.xml
+multiple-authors-source.xml
+multiple-authors.xml
+multiple-categories-entry.xml
+multiple-categories-source.xml
+multiple-categories.xml
+multiple-contributors-entry.xml
+multiple-contributors-source.xml
+multiple-contributors.xml
+###multiple-icons-source.xml This operation is not supported for a relative URI.
+###multiple-icons.xml This operation is not supported for a relative URI.
+multiple-related-matching.xml
+no-content-or-alternate.xml
+no-content-or-summary.xml
+no-name.xml
+prefixed-namespace.xml
+###rdf-extensions.xml The method or operation is not implemented.
+rel-colon.xml
+related-same-rel-type-hreflang.xml
+relative-ref.xml
+rights-text-with-escaped-html.xml
+rights-xhtml-no-xmldiv.xml
+self-vs-alternate.xml
+subtitle-blank.xml
+summary-content-base64.xml
+summary-content-src.xml
+text_with_escaped_html.xml
+title-blank.xml
+###trackback-about-entry.xml The method or operation is not implemented.
+### trackback-ping-entry.xml The method or operation is not implemented.
+trackback-ping-outside-entry.xml
+type-html.xml
+type-multipart-alternative.xml
+type-text-html.xml
+type-text.xml
+type-xhtml.xml
+type-xml.xml
+undeterminable-vocabulary.xml
+undeterminable-vocabulary2.xml
+undeterminable-vocabulary3.xml
+unregistered-rel.xml
+updated-example3.xml
+valid-xml-base-iri.xml
+ws-author-uri.xml
+ws-category-scheme.xml
+ws-content-src.xml
+ws-entry-id.xml
+ws-entry-published.xml
+ws-entry-updated.xml
+ws-feed-icon.xml
+ws-feed-id.xml
+ws-feed-logo.xml
+ws-feed-updated.xml
+ws-generator-uri.xml
+ws-link-href.xml
+ws-link-rel.xml
+###xhtml-extensions.xml The method or operation is not implemented.
+xml-base-ambiguous.xml
+xml-base-elem-ne-doc.xml
+xml-base.xml
+xml-lang-blank.xml
+###xml-lang.xml The method or operation is not implemented.
+zero-entries.xml
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Description: No errors should be produced by a minimal entry
+Expect: !Error
+-->
+
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary type="text">Some text.</summary>
+ <category term="MyCategory" />
+ <author>
+ <name>John Doe</name>
+ </author>
+</entry>
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace System.ServiceModel.Syndication.Tests
+{
+ public class AllowableDifference
+ {
+ public AllowableDifference(string file1Value, string file2Value)
+ {
+ File1Value = file1Value;
+ File2Value = file2Value;
+ }
+
+ public string File1Value;
+ public string File2Value;
+ }
+
+ public class CompareHelper
+ {
+ private List<AllowableDifference> _allowableDifferences = null;
+
+ private XmlDiff _diff;
+
+ public List<AllowableDifference> AllowableDifferences
+ {
+ get
+ {
+ return _allowableDifferences;
+ }
+ set
+ {
+ _allowableDifferences = value;
+ }
+ }
+
+ public XmlDiff Diff
+ {
+ get
+ {
+ return _diff;
+ }
+ set
+ {
+ _diff = value;
+ }
+ }
+ public bool Compare(string source, string target)
+ {
+ if (Diff.Compare(source, target))
+ {
+ return true;
+ }
+ else
+ {
+ XmlDocument diffDoc = new XmlDocument();
+ diffDoc.LoadXml(Diff.ToXml());
+ XmlNodeList totalFailures = diffDoc.SelectNodes("/Root/Node/Diff[@DiffType]");
+ XmlNodeList attrFailures = diffDoc.SelectNodes("/Root/Node/Diff[@DiffType=6]|/Root/Node/Diff[@DiffType=5]|/Root/Node/Diff[@DiffType=1]");
+
+ if (attrFailures.Count == totalFailures.Count)
+ {
+ bool allFailuresAllowed = true;
+ foreach (XmlNode node in attrFailures)
+ {
+ if (!IsAllowableFailure(node))
+ {
+ allFailuresAllowed = false;
+ break;
+ }
+ }
+ return allFailuresAllowed;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ private bool IsAllowableFailure(XmlNode failedNode)
+ {
+ //DiffType="1" is <x /> vs. <x></x>, ignore
+ XmlAttribute diffType;
+ if ((diffType = failedNode.Attributes["DiffType"]) != null)
+ {
+ if (diffType.Value == "1") return true;
+ }
+ if (failedNode.ChildNodes.Count < 2) throw new ArgumentException("Unexpected node structure", "failedNode");
+ if (AllowableDifferences == null) return false;
+
+ // XmlDiff flags closing tags as different when the open tags were different
+ // this flags those since they aren't interesting failures
+ if (failedNode.ChildNodes[0].InnerText.StartsWith("</") &&
+ failedNode.ChildNodes[1].InnerText.StartsWith("</"))
+ {
+ return true;
+ }
+
+ foreach (AllowableDifference diff in AllowableDifferences)
+ {
+ if (failedNode.ChildNodes[0].InnerText == diff.File1Value &&
+ failedNode.ChildNodes[1].InnerText == diff.File2Value)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
--- /dev/null
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace System.ServiceModel.Syndication.Tests
+{
+ internal enum DiffType
+ {
+ None,
+ Success,
+ Element,
+ Whitespace,
+ Comment,
+ PI,
+ Text,
+ CData,
+ Attribute,
+ NS,
+ Prefix,
+ SourceExtra,
+ TargetExtra,
+ NodeType
+ }
+
+ public class XmlDiff
+ {
+ private XmlDiffDocument _SourceDoc;
+ private XmlDiffDocument _TargetDoc;
+
+ private XmlTextWriter _Writer; // Writer to write out the result
+ private StringBuilder _Output;
+
+ // Option Flags
+ private XmlDiffOption _XmlDiffOption = XmlDiffOption.None;
+
+ public XmlDiff()
+ {
+ _XmlDiffOption = XmlDiffOption.IgnoreEmptyElement |
+ XmlDiffOption.IgnoreWhitespace |
+ XmlDiffOption.IgnoreAttributeOrder |
+ XmlDiffOption.IgnoreNS |
+ XmlDiffOption.IgnorePrefix |
+ XmlDiffOption.IgnoreDTD |
+ XmlDiffOption.IgnoreChildOrder;
+ }
+
+ public XmlDiffOption Option
+ {
+ get
+ {
+ return _XmlDiffOption;
+ }
+ set
+ {
+ _XmlDiffOption = value;
+ }
+ }
+
+ internal bool IgnoreEmptyElement
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreEmptyElement) != 0); }
+ }
+
+ internal bool IgnoreComments
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreComments) != 0); }
+ }
+
+ internal bool IgnoreAttributeOrder
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreAttributeOrder) != 0); }
+ }
+
+ internal bool IgnoreWhitespace
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreWhitespace) != 0); }
+ }
+
+ internal bool IgnoreNS
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreNS) != 0); }
+ }
+
+ internal bool IgnorePrefix
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnorePrefix) != 0); }
+ }
+
+ internal bool IgnoreDTD
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreDTD) != 0); }
+ }
+
+ internal bool IgnoreChildOrder
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.IgnoreChildOrder) != 0); }
+ }
+
+ internal bool ConcatenateAdjacentTextNodes
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.ConcatenateAdjacentTextNodes) != 0); }
+ }
+
+ internal bool TreatWhitespaceTextAsWSNode
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.TreatWhitespaceTextAsWSNode) != 0); }
+ }
+
+ internal bool ParseAttributeValuesAsQName
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.ParseAttributeValuesAsQName) != 0); }
+ }
+
+ internal bool DontWriteMatchingNodesToOutput
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.DontWriteMatchingNodesToOutput) != 0); }
+ }
+
+ internal bool DontWriteAnythingToOutput
+ {
+ get { return ((_XmlDiffOption & XmlDiffOption.DontWriteAnythingToOutput) != 0); }
+ }
+
+ private void InitFiles()
+ {
+ _SourceDoc = new XmlDiffDocument();
+ _SourceDoc.Option = _XmlDiffOption;
+ _TargetDoc = new XmlDiffDocument();
+ _TargetDoc.Option = this.Option;
+ _Output = new StringBuilder(String.Empty);
+ }
+
+ public bool Compare(String source, String target)
+ {
+ InitFiles();
+ _SourceDoc.Load(source);
+ _TargetDoc.Load(target);
+ return Diff();
+ }
+
+ public bool Compare(XmlReader source, XmlReader target)
+ {
+ InitFiles();
+ _SourceDoc.Load(source);
+ _TargetDoc.Load(target);
+ return Diff();
+ }
+
+ public bool Compare(XmlReader source, XmlReader target, XmlDiffAdvancedOptions advOptions)
+ {
+ InitFiles();
+
+ _SourceDoc.Load(source);
+ _TargetDoc.Load(target);
+ XPathNavigator nav = _SourceDoc.CreateNavigator();
+
+ if (!string.IsNullOrEmpty(advOptions.IgnoreChildOrderExpr))
+ {
+ XPathExpression expr = GenerateXPathExpression(
+ advOptions.IgnoreChildOrderExpr,
+ advOptions,
+ nav);
+
+ _SourceDoc.SortChildren(expr);
+ _TargetDoc.SortChildren(expr);
+ }
+
+ if (advOptions.IgnoreNodesExpr != null && advOptions.IgnoreNodesExpr != "")
+ {
+ XPathExpression expr = GenerateXPathExpression(
+ advOptions.IgnoreNodesExpr,
+ advOptions,
+ nav);
+
+ _SourceDoc.IgnoreNodes(expr);
+ _TargetDoc.IgnoreNodes(expr);
+ }
+
+ if (advOptions.IgnoreValuesExpr != null && advOptions.IgnoreValuesExpr != "")
+ {
+ XPathExpression expr = GenerateXPathExpression(
+ advOptions.IgnoreValuesExpr,
+ advOptions,
+ nav);
+
+ _SourceDoc.IgnoreValues(expr);
+ _TargetDoc.IgnoreValues(expr);
+ }
+
+ return Diff();
+ }
+
+ private static XPathExpression GenerateXPathExpression(string expression, XmlDiffAdvancedOptions advOptions, XPathNavigator nav)
+ {
+ XPathExpression expr = nav.Compile(expression);
+
+ if (advOptions.HadAddedNamespace())
+ {
+ XmlNamespaceManager xnm = new XmlNamespaceManager(nav.NameTable);
+
+ foreach (KeyValuePair<string, string> each in advOptions.AddedNamespaces)
+ {
+ xnm.AddNamespace(each.Key, each.Value);
+ }
+
+ expr.SetContext(xnm);
+ }
+
+ return expr;
+ }
+
+
+ private bool Diff()
+ {
+ bool flag = false;
+ _Writer = new XmlTextWriter(new StringWriter(_Output));
+ _Writer.WriteStartElement(String.Empty, "Root", String.Empty);
+
+ flag = CompareChildren(_SourceDoc, _TargetDoc);
+
+ _Writer.WriteEndElement();
+ _Writer.Close();
+ return flag;
+ }
+
+ // This function is being called recursively to compare the children of a certain node.
+ // When calling this function the navigator should be pointing at the parent node whose children
+ // we wants to compare and return the navigator back to the same node before exiting from it.
+ private bool CompareChildren(XmlDiffNode sourceNode, XmlDiffNode targetNode)
+ {
+ XmlDiffNode sourceChild = sourceNode.FirstChild;
+ XmlDiffNode targetChild = targetNode.FirstChild;
+
+ bool flag = true;
+ bool tempFlag = true;
+
+ DiffType result;
+
+ // Loop to compare all the child elements of the parent node
+ while (sourceChild != null || targetChild != null)
+ {
+ //Console.WriteLine( (sourceChild!=null)?(sourceChild.NodeType.ToString()):"null" );
+ //Console.WriteLine( (targetChild!=null)?(targetChild.NodeType.ToString()):"null" );
+ if (sourceChild != null)
+ {
+ if (targetChild != null)
+ {
+ // Both Source and Target Read successful
+ if ((result = CompareNodes(sourceChild, targetChild)) == DiffType.Success)
+ {
+ // Child nodes compared successfully, write out the result
+ WriteResult(sourceChild, targetChild, DiffType.Success);
+ // Check whether this Node has Children, if it does call CompareChildren recursively
+ if (sourceChild.FirstChild != null)
+ {
+ tempFlag = CompareChildren(sourceChild, targetChild);
+ }
+ else if (targetChild.FirstChild != null)
+ {
+ WriteResult(null, targetChild, DiffType.TargetExtra);
+ tempFlag = false;
+ }
+ // set the compare flag
+ flag = (flag && tempFlag);
+
+ // Writing out End Element to the result
+ if (sourceChild.NodeType == XmlDiffNodeType.Element && !(sourceChild is XmlDiffEmptyElement))
+ {
+ XmlDiffElement sourceElem = sourceChild as XmlDiffElement;
+ XmlDiffElement targetElem = targetChild as XmlDiffElement;
+ Debug.Assert(sourceElem != null);
+ Debug.Assert(targetElem != null);
+ if (!DontWriteMatchingNodesToOutput && !DontWriteAnythingToOutput)
+ {
+ _Writer.WriteStartElement(String.Empty, "Node", String.Empty);
+ _Writer.WriteAttributeString(String.Empty, "SourceLineNum", String.Empty, sourceElem.EndLineNumber.ToString());
+ _Writer.WriteAttributeString(String.Empty, "SourceLinePos", String.Empty, sourceElem.EndLinePosition.ToString());
+ _Writer.WriteAttributeString(String.Empty, "TargetLineNum", String.Empty, targetElem.EndLineNumber.ToString());
+ _Writer.WriteAttributeString(String.Empty, "TargetLinePos", String.Empty, targetElem.EndLinePosition.ToString());
+ _Writer.WriteStartElement(String.Empty, "Diff", String.Empty);
+ _Writer.WriteEndElement();
+
+ _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty);
+ _Writer.WriteCData("</" + sourceElem.Name + ">");
+ _Writer.WriteEndElement();
+ _Writer.WriteEndElement();
+ }
+ }
+
+ // Move to Next child
+ sourceChild = sourceChild.NextSibling;
+ targetChild = targetChild.NextSibling;
+ }
+ else
+ {
+ // Child nodes not matched, start the recovery process
+ bool recoveryFlag = false;
+
+ // Try to match the source node with the target nodes at the same level
+ XmlDiffNode backupTargetChild = targetChild.NextSibling;
+ while (!recoveryFlag && backupTargetChild != null)
+ {
+ if (CompareNodes(sourceChild, backupTargetChild) == DiffType.Success)
+ {
+ recoveryFlag = true;
+ do
+ {
+ WriteResult(null, targetChild, DiffType.TargetExtra);
+ targetChild = targetChild.NextSibling;
+ } while (targetChild != backupTargetChild);
+ break;
+ }
+ backupTargetChild = backupTargetChild.NextSibling;
+ }
+
+ // If not recovered, try to match the target node with the source nodes at the same level
+ if (!recoveryFlag)
+ {
+ XmlDiffNode backupSourceChild = sourceChild.NextSibling;
+ while (!recoveryFlag && backupSourceChild != null)
+ {
+ if (CompareNodes(backupSourceChild, targetChild) == DiffType.Success)
+ {
+ recoveryFlag = true;
+ do
+ {
+ WriteResult(sourceChild, null, DiffType.SourceExtra);
+ sourceChild = sourceChild.NextSibling;
+ } while (sourceChild != backupSourceChild);
+ break;
+ }
+ backupSourceChild = backupSourceChild.NextSibling;
+ }
+ }
+
+ // If still not recovered, write both of them as different nodes and move on
+ if (!recoveryFlag)
+ {
+ WriteResult(sourceChild, targetChild, result);
+
+ // Check whether this Node has Children, if it does call CompareChildren recursively
+ if (sourceChild.FirstChild != null)
+ {
+ tempFlag = CompareChildren(sourceChild, targetChild);
+ }
+ else if (targetChild.FirstChild != null)
+ {
+ WriteResult(null, targetChild, DiffType.TargetExtra);
+ tempFlag = false;
+ }
+
+ // Writing out End Element to the result
+ bool bSourceNonEmpElemEnd = (sourceChild.NodeType == XmlDiffNodeType.Element && !(sourceChild is XmlDiffEmptyElement));
+ bool bTargetNonEmpElemEnd = (targetChild.NodeType == XmlDiffNodeType.Element && !(targetChild is XmlDiffEmptyElement));
+ if (bSourceNonEmpElemEnd || bTargetNonEmpElemEnd)
+ {
+ XmlDiffElement sourceElem = sourceChild as XmlDiffElement;
+ XmlDiffElement targetElem = targetChild as XmlDiffElement;
+ if (!DontWriteAnythingToOutput)
+ {
+ _Writer.WriteStartElement(String.Empty, "Node", String.Empty);
+ _Writer.WriteAttributeString(String.Empty, "SourceLineNum", String.Empty, (sourceElem != null) ? sourceElem.EndLineNumber.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "SourceLinePos", String.Empty, (sourceElem != null) ? sourceElem.EndLinePosition.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "TargetLineNum", String.Empty, (targetElem != null) ? targetElem.EndLineNumber.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "TargetLinePos", String.Empty, (targetElem != null) ? targetElem.EndLineNumber.ToString() : "-1");
+ _Writer.WriteStartElement(String.Empty, "Diff", String.Empty);
+ _Writer.WriteAttributeString(String.Empty, "DiffType", String.Empty, GetDiffType(result));
+ if (bSourceNonEmpElemEnd)
+ {
+ _Writer.WriteStartElement(String.Empty, "File1", String.Empty);
+ _Writer.WriteCData("</" + sourceElem.Name + ">");
+ _Writer.WriteEndElement();
+ }
+
+ if (bTargetNonEmpElemEnd)
+ {
+ _Writer.WriteStartElement(String.Empty, "File2", String.Empty);
+ _Writer.WriteCData("</" + targetElem.Name + ">");
+ _Writer.WriteEndElement();
+ }
+
+ _Writer.WriteEndElement();
+
+ _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty);
+ _Writer.WriteEndElement();
+ _Writer.WriteEndElement();
+ }
+ }
+
+ sourceChild = sourceChild.NextSibling;
+ targetChild = targetChild.NextSibling;
+ }
+
+ flag = false;
+ }
+ }
+ else
+ {
+ // SourceRead NOT NULL targetRead is NULL
+ WriteResult(sourceChild, null, DiffType.SourceExtra);
+ flag = false;
+ sourceChild = sourceChild.NextSibling;
+ }
+ }
+ else if (targetChild != null)
+ {
+ // SourceRead is NULL and targetRead is NOT NULL
+ WriteResult(null, targetChild, DiffType.TargetExtra);
+ flag = false;
+ targetChild = targetChild.NextSibling;
+ }
+ else
+ {
+ //Both SourceRead and TargetRead is NULL
+ Debug.Assert(false, "Impossible Situation for comparison");
+ }
+ }
+ return flag;
+ }
+
+ /// <summary>
+ /// Combines multiple adjacent text nodes into a single node.
+ /// Sometimes the binary reader/writer will break text nodes in multiple
+ /// nodes; i.e., if the user calls
+ /// <code>writer.WriteString("foo"); writer.WriteString("bar")</code>
+ /// on the writer and then iterate calling reader.Read() on the document, the binary
+ /// reader will report two text nodes ("foo", "bar"), while the
+ /// other readers will report a single text node ("foobar") – notice that
+ /// this is not a problem; calling ReadString, or Read[Element]ContentAsString in
+ /// all readers will return "foobar".
+ /// </summary>
+ /// <param name="node">the node to be normalized. Any siblings of
+ /// type XmlDiffCharacterData will be removed, with their values appended
+ /// to the value of this node</param>
+ private void DoConcatenateAdjacentTextNodes(XmlDiffCharacterData node)
+ {
+ if (node.NextSibling == null) return;
+ if (!(node.NextSibling is XmlDiffCharacterData)) return;
+ StringBuilder sb = new StringBuilder();
+ sb.Append(node.Value);
+ XmlDiffCharacterData nextNode = (node.NextSibling as XmlDiffCharacterData);
+ while (nextNode != null)
+ {
+ sb.Append(nextNode.Value);
+ XmlDiffCharacterData curNextNode = nextNode;
+ nextNode = (nextNode.NextSibling as XmlDiffCharacterData);
+ curNextNode.ParentNode.DeleteChild(curNextNode);
+ }
+ node.Value = sb.ToString();
+ }
+
+ // This function compares the two nodes passed to it, depending upon the options set by the user.
+ private DiffType CompareNodes(XmlDiffNode sourceNode, XmlDiffNode targetNode)
+ {
+ if (sourceNode.NodeType != targetNode.NodeType)
+ {
+ return DiffType.NodeType;
+ }
+ switch (sourceNode.NodeType)
+ {
+ case XmlDiffNodeType.Element:
+ XmlDiffElement sourceElem = sourceNode as XmlDiffElement;
+ XmlDiffElement targetElem = targetNode as XmlDiffElement;
+ Debug.Assert(sourceElem != null);
+ Debug.Assert(targetElem != null);
+ if (!IgnoreNS)
+ {
+ if (sourceElem.NamespaceURI != targetElem.NamespaceURI)
+ {
+ return DiffType.NS;
+ }
+ }
+ if (!IgnorePrefix)
+ {
+ if (sourceElem.Prefix != targetElem.Prefix)
+ {
+ return DiffType.Prefix;
+ }
+ }
+
+ if (sourceElem.LocalName != targetElem.LocalName)
+ {
+ return DiffType.Element;
+ }
+ if (!IgnoreEmptyElement)
+ {
+ if ((sourceElem is XmlDiffEmptyElement) != (targetElem is XmlDiffEmptyElement))
+ {
+ return DiffType.Element;
+ }
+ }
+ if (!CompareAttributes(sourceElem, targetElem))
+ {
+ return DiffType.Attribute;
+ }
+ break;
+ case XmlDiffNodeType.Text:
+ case XmlDiffNodeType.Comment:
+ case XmlDiffNodeType.WS:
+ XmlDiffCharacterData sourceText = sourceNode as XmlDiffCharacterData;
+ XmlDiffCharacterData targetText = targetNode as XmlDiffCharacterData;
+ Debug.Assert(sourceText != null);
+ Debug.Assert(targetText != null);
+
+ if (ConcatenateAdjacentTextNodes)
+ {
+ DoConcatenateAdjacentTextNodes(sourceText);
+ DoConcatenateAdjacentTextNodes(targetText);
+ }
+
+ if (IgnoreWhitespace)
+ {
+ if (sourceText.Value.Trim() == targetText.Value.Trim())
+ {
+ return DiffType.Success;
+ }
+ }
+ else
+ {
+ if (sourceText.Value == targetText.Value)
+ {
+ return DiffType.Success;
+ }
+ }
+ if (sourceText.NodeType == XmlDiffNodeType.Text || sourceText.NodeType == XmlDiffNodeType.WS) //should ws nodes also as text nodes???
+ {
+ return DiffType.Text;
+ }
+ else if (sourceText.NodeType == XmlDiffNodeType.Comment)
+ {
+ return DiffType.Comment;
+ }
+ else if (sourceText.NodeType == XmlDiffNodeType.CData)
+ {
+ return DiffType.CData;
+ }
+ else
+ {
+ return DiffType.None;
+ }
+ case XmlDiffNodeType.PI:
+ XmlDiffProcessingInstruction sourcePI = sourceNode as XmlDiffProcessingInstruction;
+ XmlDiffProcessingInstruction targetPI = targetNode as XmlDiffProcessingInstruction;
+ Debug.Assert(sourcePI != null);
+ Debug.Assert(targetPI != null);
+ if (sourcePI.Name != targetPI.Name || sourcePI.Value != targetPI.Value)
+ {
+ return DiffType.PI;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return DiffType.Success;
+ }
+
+ // This function writes the result in XML format so that it can be used by other applications to display the diff
+ private void WriteResult(XmlDiffNode sourceNode, XmlDiffNode targetNode, DiffType result)
+ {
+ if (DontWriteAnythingToOutput) return;
+
+ if (result != DiffType.Success || !DontWriteMatchingNodesToOutput)
+ {
+ _Writer.WriteStartElement(String.Empty, "Node", String.Empty);
+ _Writer.WriteAttributeString(String.Empty, "SourceLineNum", String.Empty, (sourceNode != null) ? sourceNode.LineNumber.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "SourceLinePos", String.Empty, (sourceNode != null) ? sourceNode.LinePosition.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "TargetLineNum", String.Empty, (targetNode != null) ? targetNode.LineNumber.ToString() : "-1");
+ _Writer.WriteAttributeString(String.Empty, "TargetLinePos", String.Empty, (targetNode != null) ? targetNode.LinePosition.ToString() : "-1");
+ }
+ if (result == DiffType.Success)
+ {
+ if (!DontWriteMatchingNodesToOutput)
+ {
+ _Writer.WriteStartElement(String.Empty, "Diff", String.Empty);
+ _Writer.WriteEndElement();
+
+ _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty);
+ if (sourceNode.NodeType == XmlDiffNodeType.CData)
+ {
+ _Writer.WriteString("<![CDATA[");
+ _Writer.WriteCData(GetNodeText(sourceNode, result));
+ _Writer.WriteString("]]>");
+ }
+ else
+ {
+ _Writer.WriteCData(GetNodeText(sourceNode, result));
+ }
+ _Writer.WriteEndElement();
+ }
+ }
+ else
+ {
+ _Writer.WriteStartElement(String.Empty, "Diff", String.Empty);
+ _Writer.WriteAttributeString(String.Empty, "DiffType", String.Empty, GetDiffType(result));
+
+ if (sourceNode != null)
+ {
+ _Writer.WriteStartElement(String.Empty, "File1", String.Empty);
+ if (sourceNode.NodeType == XmlDiffNodeType.CData)
+ {
+ _Writer.WriteString("<![CDATA[");
+ _Writer.WriteCData(GetNodeText(sourceNode, result));
+ _Writer.WriteString("]]>");
+ }
+ else
+ {
+ _Writer.WriteString(GetNodeText(sourceNode, result));
+ }
+ _Writer.WriteEndElement();
+ }
+
+ if (targetNode != null)
+ {
+ _Writer.WriteStartElement(String.Empty, "File2", String.Empty);
+ if (targetNode.NodeType == XmlDiffNodeType.CData)
+ {
+ _Writer.WriteString("<![CDATA[");
+ _Writer.WriteCData(GetNodeText(targetNode, result));
+ _Writer.WriteString("]]>");
+ }
+ else
+ {
+ _Writer.WriteString(GetNodeText(targetNode, result));
+ }
+ _Writer.WriteEndElement();
+ }
+
+ _Writer.WriteEndElement();
+
+ _Writer.WriteStartElement(String.Empty, "Lexical-equal", String.Empty);
+ _Writer.WriteEndElement();
+ }
+ if (result != DiffType.Success || !DontWriteMatchingNodesToOutput)
+ {
+ _Writer.WriteEndElement();
+ }
+ }
+
+ // This is a helper function for WriteResult. It gets the Xml representation of the different node we wants
+ // to write out and all it's children.
+ private String GetNodeText(XmlDiffNode diffNode, DiffType result)
+ {
+ string text = string.Empty;
+ switch (diffNode.NodeType)
+ {
+ case XmlDiffNodeType.Element:
+ if (result == DiffType.SourceExtra || result == DiffType.TargetExtra)
+ return diffNode.OuterXml;
+ StringWriter str = new StringWriter();
+ XmlTextWriter writer = new XmlTextWriter(str);
+ XmlDiffElement diffElem = diffNode as XmlDiffElement;
+ Debug.Assert(diffNode != null);
+ writer.WriteStartElement(diffElem.Prefix, diffElem.LocalName, diffElem.NamespaceURI);
+ XmlDiffAttribute diffAttr = diffElem.FirstAttribute;
+ while (diffAttr != null)
+ {
+ writer.WriteAttributeString(diffAttr.Prefix, diffAttr.LocalName, diffAttr.NamespaceURI, diffAttr.Value);
+ diffAttr = (XmlDiffAttribute)diffAttr.NextSibling;
+ }
+ if (diffElem is XmlDiffEmptyElement)
+ {
+ writer.WriteEndElement();
+ text = str.ToString();
+ }
+ else
+ {
+ text = str.ToString();
+ text += ">";
+ }
+ writer.Close();
+ break;
+ case XmlDiffNodeType.CData:
+ text = ((XmlDiffCharacterData)diffNode).Value;
+ break;
+ default:
+ text = diffNode.OuterXml;
+ break;
+ }
+ return text;
+ }
+
+ // This function is used to compare the attributes of an element node according to the options set by the user.
+ private bool CompareAttributes(XmlDiffElement sourceElem, XmlDiffElement targetElem)
+ {
+ Debug.Assert(sourceElem != null);
+ Debug.Assert(targetElem != null);
+ if (sourceElem.AttributeCount != targetElem.AttributeCount)
+ return false;
+
+ if (sourceElem.AttributeCount == 0)
+ return true;
+
+ XmlDiffAttribute sourceAttr = sourceElem.FirstAttribute;
+ XmlDiffAttribute targetAttr = targetElem.FirstAttribute;
+
+ const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
+
+ if (!IgnoreAttributeOrder)
+ {
+ while (sourceAttr != null && targetAttr != null)
+ {
+ if (!IgnoreNS)
+ {
+ if (sourceAttr.NamespaceURI != targetAttr.NamespaceURI)
+ {
+ return false;
+ }
+ }
+
+ if (!IgnorePrefix)
+ {
+ if (sourceAttr.Prefix != targetAttr.Prefix)
+ {
+ return false;
+ }
+ }
+
+ if (sourceAttr.NamespaceURI == xmlnsNamespace && targetAttr.NamespaceURI == xmlnsNamespace)
+ {
+ if (!IgnorePrefix && (sourceAttr.LocalName != targetAttr.LocalName))
+ {
+ return false;
+ }
+ if (!IgnoreNS && (sourceAttr.Value != targetAttr.Value))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (sourceAttr.LocalName != targetAttr.LocalName)
+ {
+ return false;
+ }
+ if (sourceAttr.Value != targetAttr.Value)
+ {
+ if (ParseAttributeValuesAsQName)
+ {
+ if (sourceAttr.ValueAsQName != null)
+ {
+ if (!sourceAttr.ValueAsQName.Equals(targetAttr.ValueAsQName)) return false;
+ }
+ else
+ {
+ if (targetAttr.ValueAsQName != null) return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ sourceAttr = (XmlDiffAttribute)(sourceAttr.NextSibling);
+ targetAttr = (XmlDiffAttribute)(targetAttr.NextSibling);
+ }
+ }
+ else
+ {
+ Hashtable sourceAttributeMap = new Hashtable();
+ Hashtable targetAttributeMap = new Hashtable();
+
+ while (sourceAttr != null && targetAttr != null)
+ {
+ if (IgnorePrefix && sourceAttr.NamespaceURI == xmlnsNamespace)
+ {
+ // do nothing
+ }
+ else
+ {
+ string localNameAndNamespace = sourceAttr.LocalName + "<&&>" + sourceAttr.NamespaceURI;
+ sourceAttributeMap.Add(localNameAndNamespace, sourceAttr);
+ }
+ if (IgnorePrefix && targetAttr.NamespaceURI == xmlnsNamespace)
+ {
+ // do nothing
+ }
+ else
+ {
+ string localNameAndNamespace = targetAttr.LocalName + "<&&>" + targetAttr.NamespaceURI;
+ targetAttributeMap.Add(localNameAndNamespace, targetAttr);
+ }
+
+ sourceAttr = (XmlDiffAttribute)(sourceAttr.NextSibling);
+ targetAttr = (XmlDiffAttribute)(targetAttr.NextSibling);
+ }
+
+ if (sourceAttributeMap.Count != targetAttributeMap.Count)
+ {
+ return false;
+ }
+
+ foreach (string sourceKey in sourceAttributeMap.Keys)
+ {
+ if (!targetAttributeMap.ContainsKey(sourceKey))
+ {
+ return false;
+ }
+ sourceAttr = (XmlDiffAttribute)sourceAttributeMap[sourceKey];
+ targetAttr = (XmlDiffAttribute)targetAttributeMap[sourceKey];
+
+ if (!IgnorePrefix)
+ {
+ if (sourceAttr.Prefix != targetAttr.Prefix)
+ {
+ return false;
+ }
+ }
+
+ if (sourceAttr.Value != targetAttr.Value)
+ {
+ if (ParseAttributeValuesAsQName)
+ {
+ if (sourceAttr.ValueAsQName != null)
+ {
+ if (!sourceAttr.ValueAsQName.Equals(targetAttr.ValueAsQName)) return false;
+ }
+ else
+ {
+ if (targetAttr.ValueAsQName != null) return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ public string ToXml()
+ {
+ if (_Output != null)
+ return _Output.ToString();
+ return string.Empty;
+ }
+
+ public void ToXml(string fileName)
+ {
+ FileStream file;
+ file = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
+ StreamWriter writer = new StreamWriter(file);
+ writer.Write("<?xml-stylesheet type='text/xsl' href='diff.xsl'?>");
+ writer.Write(ToXml());
+ writer.Close();
+ file.Close();
+ }
+
+ public void ToXml(Stream stream)
+ {
+ StreamWriter writer = new StreamWriter(stream);
+ writer.Write("<?xml-stylesheet type='text/xsl' href='diff.xsl'?>");
+ writer.Write(ToXml());
+ writer.Close();
+ }
+
+ private String GetDiffType(DiffType type)
+ {
+ switch (type)
+ {
+ case DiffType.None:
+ return String.Empty;
+ case DiffType.Element:
+ return "1";
+ case DiffType.Whitespace:
+ return "2";
+ case DiffType.Comment:
+ return "3";
+ case DiffType.PI:
+ return "4";
+ case DiffType.Text:
+ return "5";
+ case DiffType.Attribute:
+ return "6";
+ case DiffType.NS:
+ return "7";
+ case DiffType.Prefix:
+ return "8";
+ case DiffType.SourceExtra:
+ return "9";
+ case DiffType.TargetExtra:
+ return "10";
+ case DiffType.NodeType:
+ return "11";
+ case DiffType.CData:
+ return "12";
+ default:
+ return String.Empty;
+ }
+ }
+ }
+}
--- /dev/null
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace System.ServiceModel.Syndication.Tests
+{
+ public enum NodePosition
+ {
+ Before = 0,
+ After = 1,
+ Unknown = 2
+ }
+
+ public enum XmlDiffNodeType
+ {
+ Element = 0,
+ Attribute = 1,
+ ER = 2,
+ Text = 3,
+ CData = 4,
+ Comment = 5,
+ PI = 6,
+ WS = 7,
+ Document = 8
+ }
+
+ internal class PositionInfo : IXmlLineInfo
+ {
+ public virtual bool HasLineInfo() { return false; }
+ public virtual int LineNumber { get { return 0; } }
+ public virtual int LinePosition { get { return 0; } }
+
+ public static PositionInfo GetPositionInfo(Object o)
+ {
+ IXmlLineInfo lineInfo = o as IXmlLineInfo;
+ if (lineInfo != null && lineInfo.HasLineInfo())
+ {
+ return new ReaderPositionInfo(lineInfo);
+ }
+ else
+ {
+ return new PositionInfo();
+ }
+ }
+ }
+
+ internal class ReaderPositionInfo : PositionInfo
+ {
+ private IXmlLineInfo _mlineInfo;
+
+ public ReaderPositionInfo(IXmlLineInfo lineInfo)
+ {
+ _mlineInfo = lineInfo;
+ }
+
+ public override bool HasLineInfo() { return true; }
+ public override int LineNumber { get { return _mlineInfo.LineNumber; } }
+ public override int LinePosition { get { return _mlineInfo.LinePosition; } }
+ }
+
+ //nametable could be added for next "release"
+ public class XmlDiffNameTable
+ {
+ }
+
+
+ public class XmlDiffDocument : XmlDiffNode, IXPathNavigable
+ {
+ //XmlDiffNameTable _nt;
+ private bool _bLoaded;
+ private bool _bIgnoreAttributeOrder;
+ private bool _bIgnoreChildOrder;
+ private bool _bIgnoreComments;
+ private bool _bIgnoreWhitespace;
+ private bool _bIgnoreDTD;
+ private bool _bIgnoreNS;
+ private bool _bIgnorePrefix;
+ private bool _bCDataAsText;
+ private bool _bNormalizeNewline;
+ private bool _bTreatWhitespaceTextAsWSNode = false;
+ private bool _bIgnoreEmptyTextNodes = false;
+ private bool _bWhitespaceAsText = false;
+ public XmlNameTable nameTable;
+
+ public XmlDiffDocument()
+ : base()
+ {
+ _bLoaded = false;
+ _bIgnoreAttributeOrder = false;
+ _bIgnoreChildOrder = false;
+ _bIgnoreComments = false;
+ _bIgnoreWhitespace = false;
+ _bIgnoreDTD = false;
+ _bCDataAsText = false;
+ _bWhitespaceAsText = false;
+ }
+
+ public XmlDiffOption Option
+ {
+ set
+ {
+ this.IgnoreAttributeOrder = (((int)value & (int)(XmlDiffOption.IgnoreAttributeOrder)) > 0);
+ this.IgnoreChildOrder = (((int)value & (int)(XmlDiffOption.IgnoreChildOrder)) > 0);
+ this.IgnoreComments = (((int)value & (int)(XmlDiffOption.IgnoreComments)) > 0);
+ this.IgnoreWhitespace = (((int)value & (int)(XmlDiffOption.IgnoreWhitespace)) > 0);
+ this.IgnoreDTD = (((int)value & (int)(XmlDiffOption.IgnoreDTD)) > 0);
+ this.IgnoreNS = (((int)value & (int)(XmlDiffOption.IgnoreNS)) > 0);
+ this.IgnorePrefix = (((int)value & (int)(XmlDiffOption.IgnorePrefix)) > 0);
+ this.CDataAsText = (((int)value & (int)(XmlDiffOption.CDataAsText)) > 0);
+ this.NormalizeNewline = (((int)value & (int)(XmlDiffOption.NormalizeNewline)) > 0);
+ this.TreatWhitespaceTextAsWSNode = (((int)value & (int)(XmlDiffOption.TreatWhitespaceTextAsWSNode)) > 0);
+ this.IgnoreEmptyTextNodes = (((int)value & (int)(XmlDiffOption.IgnoreEmptyTextNodes)) > 0);
+ this.WhitespaceAsText = (((int)value & (int)(XmlDiffOption.WhitespaceAsText)) > 0);
+ }
+ }
+ public override XmlDiffNodeType NodeType { get { return XmlDiffNodeType.Document; } }
+
+ public bool IgnoreAttributeOrder
+ {
+ get { return _bIgnoreAttributeOrder; }
+ set { _bIgnoreAttributeOrder = value; }
+ }
+
+ public bool IgnoreChildOrder
+ {
+ get { return _bIgnoreChildOrder; }
+ set { _bIgnoreChildOrder = value; }
+ }
+
+ public bool IgnoreComments
+ {
+ get { return _bIgnoreComments; }
+ set { _bIgnoreComments = value; }
+ }
+
+ public bool IgnoreWhitespace
+ {
+ get { return _bIgnoreWhitespace; }
+ set { _bIgnoreWhitespace = value; }
+ }
+
+ public bool IgnoreDTD
+ {
+ get { return _bIgnoreDTD; }
+ set { _bIgnoreDTD = value; }
+ }
+
+ public bool IgnoreNS
+ {
+ get { return _bIgnoreNS; }
+ set { _bIgnoreNS = value; }
+ }
+
+ public bool IgnorePrefix
+ {
+ get { return _bIgnorePrefix; }
+ set { _bIgnorePrefix = value; }
+ }
+
+ public bool CDataAsText
+ {
+ get { return _bCDataAsText; }
+ set { _bCDataAsText = value; }
+ }
+
+ public bool NormalizeNewline
+ {
+ get { return _bNormalizeNewline; }
+ set { _bNormalizeNewline = value; }
+ }
+
+ public bool TreatWhitespaceTextAsWSNode
+ {
+ get { return _bTreatWhitespaceTextAsWSNode; }
+ set { _bTreatWhitespaceTextAsWSNode = value; }
+ }
+
+ public bool IgnoreEmptyTextNodes
+ {
+ get { return _bIgnoreEmptyTextNodes; }
+ set { _bIgnoreEmptyTextNodes = value; }
+ }
+
+ public bool WhitespaceAsText
+ {
+ get { return _bWhitespaceAsText; }
+ set { _bWhitespaceAsText = value; }
+ }
+
+ //NodePosition.Before is returned if node2 should be before node1;
+ //NodePosition.After is returned if node2 should be after node1;
+ //In any case, NodePosition.Unknown should never be returned.
+ internal NodePosition ComparePosition(XmlDiffNode node1, XmlDiffNode node2)
+ {
+ int nt1 = (int)(node1.NodeType);
+ int nt2 = (int)(node2.NodeType);
+ if (nt2 > nt1)
+ return NodePosition.After;
+ if (nt2 < nt1)
+ return NodePosition.Before;
+ //now nt1 == nt2
+ if (nt1 == (int)XmlDiffNodeType.Element)
+ {
+ return CompareElements(node1 as XmlDiffElement, node2 as XmlDiffElement);
+ }
+ else if (nt1 == (int)XmlDiffNodeType.Attribute)
+ {
+ return CompareAttributes(node1 as XmlDiffAttribute, node2 as XmlDiffAttribute);
+ }
+ else if (nt1 == (int)XmlDiffNodeType.ER)
+ {
+ return CompareERs(node1 as XmlDiffEntityReference, node2 as XmlDiffEntityReference);
+ }
+ else if (nt1 == (int)XmlDiffNodeType.PI)
+ {
+ return ComparePIs(node1 as XmlDiffProcessingInstruction, node2 as XmlDiffProcessingInstruction);
+ }
+ else if (node1 is XmlDiffCharacterData)
+ {
+ return CompareTextLikeNodes(node1 as XmlDiffCharacterData, node2 as XmlDiffCharacterData);
+ }
+ else
+ {
+ //something really wrong here, what should we do???
+ Debug.Assert(false, "ComparePosition meets an undecision situation.");
+ return NodePosition.Unknown;
+ }
+ }
+
+ private NodePosition CompareElements(XmlDiffElement elem1, XmlDiffElement elem2)
+ {
+ Debug.Assert(elem1 != null);
+ Debug.Assert(elem2 != null);
+ int nCompare = 0;
+ if ((nCompare = CompareText(elem2.LocalName, elem1.LocalName)) == 0)
+ {
+ if (IgnoreNS || (nCompare = CompareText(elem2.NamespaceURI, elem1.NamespaceURI)) == 0)
+ {
+ if (IgnorePrefix || (nCompare = CompareText(elem2.Prefix, elem1.Prefix)) == 0)
+ {
+ if ((nCompare = CompareText(elem2.Value, elem1.Value)) == 0)
+ {
+ if ((nCompare = CompareAttributes(elem2, elem1)) == 0)
+ {
+ return NodePosition.After;
+ }
+ }
+ }
+ }
+ }
+ if (nCompare > 0)
+ //elem2 > elem1
+ return NodePosition.After;
+ else
+ //elem2 < elem1
+ return NodePosition.Before;
+ }
+
+ private int CompareAttributes(XmlDiffElement elem1, XmlDiffElement elem2)
+ {
+ int count1 = elem1.AttributeCount;
+ int count2 = elem2.AttributeCount;
+ if (count1 > count2)
+ return 1;
+ else if (count1 < count2)
+ return -1;
+ else
+ {
+ XmlDiffAttribute current1 = elem1.FirstAttribute;
+ XmlDiffAttribute current2 = elem2.FirstAttribute;
+ // NodePosition result = 0;
+ int nCompare = 0;
+ while (current1 != null && current2 != null && nCompare == 0)
+ {
+ if ((nCompare = CompareText(current2.LocalName, current1.LocalName)) == 0)
+ {
+ if (IgnoreNS || (nCompare = CompareText(current2.NamespaceURI, current1.NamespaceURI)) == 0)
+ {
+ if (IgnorePrefix || (nCompare = CompareText(current2.Prefix, current1.Prefix)) == 0)
+ {
+ if ((nCompare = CompareText(current2.Value, current1.Value)) == 0)
+ {
+ //do nothing!
+ }
+ }
+ }
+ }
+ current1 = (XmlDiffAttribute)current1._next;
+ current2 = (XmlDiffAttribute)current2._next;
+ }
+ if (nCompare > 0)
+ //elem1 > attr2
+ return 1;
+ else
+ //elem1 < elem2
+ return -1;
+ }
+ }
+
+ private NodePosition CompareAttributes(XmlDiffAttribute attr1, XmlDiffAttribute attr2)
+ {
+ Debug.Assert(attr1 != null);
+ Debug.Assert(attr2 != null);
+
+ int nCompare = 0;
+ if ((nCompare = CompareText(attr2.LocalName, attr1.LocalName)) == 0)
+ {
+ if (IgnoreNS || (nCompare = CompareText(attr2.NamespaceURI, attr1.NamespaceURI)) == 0)
+ {
+ if (IgnorePrefix || (nCompare = CompareText(attr2.Prefix, attr1.Prefix)) == 0)
+ {
+ if ((nCompare = CompareText(attr2.Value, attr1.Value)) == 0)
+ {
+ return NodePosition.After;
+ }
+ }
+ }
+ }
+ if (nCompare > 0)
+ //attr2 > attr1
+ return NodePosition.After;
+ else
+ //attr2 < attr1
+ return NodePosition.Before;
+ }
+
+ private NodePosition CompareERs(XmlDiffEntityReference er1, XmlDiffEntityReference er2)
+ {
+ Debug.Assert(er1 != null);
+ Debug.Assert(er2 != null);
+
+ int nCompare = CompareText(er2.Name, er1.Name);
+ if (nCompare >= 0)
+ return NodePosition.After;
+ else
+ return NodePosition.Before;
+ }
+
+ private NodePosition ComparePIs(XmlDiffProcessingInstruction pi1, XmlDiffProcessingInstruction pi2)
+ {
+ Debug.Assert(pi1 != null);
+ Debug.Assert(pi2 != null);
+
+ int nCompare = 0;
+ if ((nCompare = CompareText(pi2.Name, pi1.Name)) == 0)
+ {
+ if ((nCompare = CompareText(pi2.Value, pi1.Value)) == 0)
+ {
+ return NodePosition.After;
+ }
+ }
+ if (nCompare > 0)
+ {
+ //pi2 > pi1
+ return NodePosition.After;
+ }
+ else
+ {
+ //pi2 < pi1
+ return NodePosition.Before;
+ }
+ }
+
+ private NodePosition CompareTextLikeNodes(XmlDiffCharacterData t1, XmlDiffCharacterData t2)
+ {
+ Debug.Assert(t1 != null);
+ Debug.Assert(t2 != null);
+
+ int nCompare = CompareText(t2.Value, t1.Value);
+ if (nCompare >= 0)
+ return NodePosition.After;
+ else
+ return NodePosition.Before;
+ }
+
+ //returns 0 if the same string; 1 if s1 > s1 and -1 if s1 < s2
+ private int CompareText(string s1, string s2)
+ {
+ return Math.Sign(String.Compare(s1, s2, StringComparison.Ordinal));
+ }
+
+ public virtual void Load(string xmlFileName)
+ {
+ XmlReaderSettings readerSettings = new XmlReaderSettings();
+ if (IgnoreDTD)
+ {
+ readerSettings.ValidationType = ValidationType.None;
+ }
+ else
+ {
+ readerSettings.ValidationType = ValidationType.DTD;
+ }
+
+ using (XmlReader reader = XmlReader.Create(xmlFileName))
+ {
+ Load(reader);
+ reader.Close();
+ }
+ }
+
+ public virtual void Load(XmlReader reader)
+ {
+ if (_bLoaded)
+ throw new InvalidOperationException("The document already contains data and should not be used again.");
+ if (reader.ReadState == ReadState.Initial)
+ {
+ if (!reader.Read())
+ {
+ return;
+ }
+ }
+ PositionInfo pInfo = PositionInfo.GetPositionInfo(reader);
+ ReadChildNodes(this, reader, pInfo);
+ _bLoaded = true;
+ this.nameTable = reader.NameTable;
+ }
+
+ internal void ReadChildNodes(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo)
+ {
+ bool lookAhead = false;
+ do
+ {
+ lookAhead = false;
+ switch (reader.NodeType)
+ {
+ case XmlNodeType.Element:
+ LoadElement(parent, reader, pInfo);
+ break;
+ case XmlNodeType.Comment:
+ if (!IgnoreComments)
+ LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.Comment);
+ break;
+ case XmlNodeType.ProcessingInstruction:
+ LoadPI(parent, reader, pInfo);
+ break;
+ case XmlNodeType.SignificantWhitespace:
+ case XmlNodeType.Whitespace:
+ if (!IgnoreWhitespace)
+ {
+ if (this.WhitespaceAsText)
+ {
+ LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.Text);
+ }
+ else
+ {
+ LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.WS);
+ }
+ }
+ break;
+ case XmlNodeType.CDATA:
+ if (!CDataAsText)
+ {
+ LoadTextNode(parent, reader, pInfo, XmlDiffNodeType.CData);
+ }
+ else //merge with adjacent text/CDATA nodes
+ {
+ StringBuilder text = new StringBuilder();
+ text.Append(reader.Value);
+ while ((lookAhead = reader.Read()) && (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.CDATA))
+ {
+ text.Append(reader.Value);
+ }
+ LoadTextNode(parent, text.ToString(), pInfo, XmlDiffNodeType.Text);
+ }
+ break;
+ case XmlNodeType.Text:
+ if (!CDataAsText)
+ {
+ LoadTextNode(parent, reader, pInfo, TextNodeIsWhitespace(reader.Value) ? XmlDiffNodeType.WS : XmlDiffNodeType.Text);
+ }
+ else //merge with adjacent text/CDATA nodes
+ {
+ StringBuilder text = new StringBuilder();
+ text.Append(reader.Value);
+ while ((lookAhead = reader.Read()) && (reader.NodeType == XmlNodeType.Text || reader.NodeType == XmlNodeType.CDATA))
+ {
+ text.Append(reader.Value);
+ }
+ string txt = text.ToString();
+ LoadTextNode(parent, txt, pInfo, TextNodeIsWhitespace(txt) ? XmlDiffNodeType.WS : XmlDiffNodeType.Text);
+ }
+ break;
+ case XmlNodeType.EntityReference:
+ LoadEntityReference(parent, reader, pInfo);
+ break;
+ case XmlNodeType.EndElement:
+ SetElementEndPosition(parent as XmlDiffElement, pInfo);
+ return;
+ case XmlNodeType.Attribute: //attribute at top level
+ string attrVal = reader.Name + "=\"" + reader.Value + "\"";
+ LoadTopLevelAttribute(parent, attrVal, pInfo, XmlDiffNodeType.Text);
+ break;
+ default:
+ break;
+ }
+ } while (lookAhead || reader.Read());
+ }
+
+ private bool TextNodeIsWhitespace(string p)
+ {
+ if (!this.TreatWhitespaceTextAsWSNode) return false;
+ for (int i = 0; i < p.Length; i++)
+ {
+ if (!Char.IsWhiteSpace(p[i])) return false;
+ }
+ return true;
+ }
+
+ private void LoadElement(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo)
+ {
+ XmlDiffElement elem = null;
+ bool bEmptyElement = reader.IsEmptyElement;
+ if (bEmptyElement)
+ elem = new XmlDiffEmptyElement(reader.LocalName, reader.Prefix, reader.NamespaceURI);
+ else
+ elem = new XmlDiffElement(reader.LocalName, reader.Prefix, reader.NamespaceURI);
+ elem.LineNumber = pInfo.LineNumber;
+ elem.LinePosition = pInfo.LinePosition;
+ ReadAttributes(elem, reader, pInfo);
+ if (!bEmptyElement)
+ {
+ // bool rtn = reader.Read();
+ // rtn = reader.Read();
+ reader.Read(); //move to child
+ ReadChildNodes(elem, reader, pInfo);
+ }
+ InsertChild(parent, elem);
+ }
+
+ private void ReadAttributes(XmlDiffElement parent, XmlReader reader, PositionInfo pInfo)
+ {
+ if (reader.MoveToFirstAttribute())
+ {
+ do
+ {
+ XmlDiffAttribute attr = new XmlDiffAttribute(reader.LocalName, reader.Prefix, reader.NamespaceURI, reader.Value);
+ attr.SetValueAsQName(reader, reader.Value);
+ attr.LineNumber = pInfo.LineNumber;
+ attr.LinePosition = pInfo.LinePosition;
+ InsertAttribute(parent, attr);
+ }
+ while (reader.MoveToNextAttribute());
+ }
+ }
+
+ private void LoadTextNode(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo, XmlDiffNodeType nt)
+ {
+ LoadTextNode(parent, reader.Value, pInfo, nt);
+ }
+
+ private void LoadTextNode(XmlDiffNode parent, string text, PositionInfo pInfo, XmlDiffNodeType nt)
+ {
+ if (!this.IgnoreEmptyTextNodes || !String.IsNullOrEmpty(text))
+ {
+ XmlDiffCharacterData textNode = new XmlDiffCharacterData(text, nt, this.NormalizeNewline);
+ textNode.LineNumber = pInfo.LineNumber;
+ textNode.LinePosition = pInfo.LinePosition;
+ InsertChild(parent, textNode);
+ }
+ }
+
+ private void LoadTopLevelAttribute(XmlDiffNode parent, string text, PositionInfo pInfo, XmlDiffNodeType nt)
+ {
+ XmlDiffCharacterData textNode = new XmlDiffCharacterData(text, nt, this.NormalizeNewline);
+ textNode.LineNumber = pInfo.LineNumber;
+ textNode.LinePosition = pInfo.LinePosition;
+ InsertTopLevelAttributeAsText(parent, textNode);
+ }
+
+ private void LoadPI(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo)
+ {
+ XmlDiffProcessingInstruction pi = new XmlDiffProcessingInstruction(reader.Name, reader.Value);
+ pi.LineNumber = pInfo.LineNumber;
+ pi.LinePosition = pInfo.LinePosition;
+ InsertChild(parent, pi);
+ }
+
+ private void LoadEntityReference(XmlDiffNode parent, XmlReader reader, PositionInfo pInfo)
+ {
+ XmlDiffEntityReference er = new XmlDiffEntityReference(reader.Name);
+ er.LineNumber = pInfo.LineNumber;
+ er.LinePosition = pInfo.LinePosition;
+ InsertChild(parent, er);
+ }
+
+ private void SetElementEndPosition(XmlDiffElement elem, PositionInfo pInfo)
+ {
+ Debug.Assert(elem != null);
+ elem.EndLineNumber = pInfo.LineNumber;
+ elem.EndLinePosition = pInfo.LinePosition;
+ }
+
+
+ private void InsertChild(XmlDiffNode parent, XmlDiffNode newChild)
+ {
+ if (IgnoreChildOrder)
+ {
+ XmlDiffNode child = parent.FirstChild;
+ XmlDiffNode prevChild = null;
+ while (child != null && (ComparePosition(child, newChild) == NodePosition.After))
+ {
+ prevChild = child;
+ child = child.NextSibling;
+ }
+ parent.InsertChildAfter(prevChild, newChild);
+ }
+ else
+ parent.InsertChildAfter(parent.LastChild, newChild);
+ }
+
+ private void InsertTopLevelAttributeAsText(XmlDiffNode parent, XmlDiffCharacterData newChild)
+ {
+ if (parent.LastChild != null && (parent.LastChild.NodeType == XmlDiffNodeType.Text || parent.LastChild.NodeType == XmlDiffNodeType.WS))
+ {
+ ((XmlDiffCharacterData)parent.LastChild).Value = ((XmlDiffCharacterData)parent.LastChild).Value + " " + newChild.Value;
+ }
+ else
+ {
+ parent.InsertChildAfter(parent.LastChild, newChild);
+ }
+ }
+
+ private void InsertAttribute(XmlDiffElement parent, XmlDiffAttribute newAttr)
+ {
+ Debug.Assert(parent != null);
+ Debug.Assert(newAttr != null);
+ newAttr._parent = parent;
+ if (IgnoreAttributeOrder)
+ {
+ XmlDiffAttribute attr = parent.FirstAttribute;
+ XmlDiffAttribute prevAttr = null;
+ while (attr != null && (CompareAttributes(attr, newAttr) == NodePosition.After))
+ {
+ prevAttr = attr;
+ attr = (XmlDiffAttribute)(attr.NextSibling);
+ }
+ parent.InsertAttributeAfter(prevAttr, newAttr);
+ }
+ else
+ parent.InsertAttributeAfter(parent.LastAttribute, newAttr);
+ }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ WriteContentTo(w);
+ }
+
+ public override void WriteContentTo(XmlWriter w)
+ {
+ XmlDiffNode child = FirstChild;
+ while (child != null)
+ {
+ child.WriteTo(w);
+ child = child.NextSibling;
+ }
+ }
+
+ //IXPathNavigable override
+ public XPathNavigator CreateNavigator()
+ {
+ return new XmlDiffNavigator(this);
+ }
+
+ /*
+ public void SortChildren(string expr, XmlNamespaceManager mngr)
+ {
+ XPathNavigator _nav = this.CreateNavigator();
+ XPathExpression _expr = _nav.Compile(expr);
+ if(mngr != null)
+ {
+ _expr.SetContext(mngr);
+ }
+ XPathNodeIterator _iter = _nav.Select(_expr);
+ while(_iter.MoveNext())
+ {
+ if(((XmlDiffNavigator)_iter.Current).CurrentNode is XmlDiffElement)
+ {
+ SortChildren((XmlDiffElement)((XmlDiffNavigator)_iter.Current).CurrentNode);
+ }
+ }
+ }
+ */
+
+ public void SortChildren(XPathExpression expr)
+ {
+ if (expr == null)
+ {
+ return;
+ }
+ XPathNavigator _nav = this.CreateNavigator();
+ XPathNodeIterator _iter = _nav.Select(expr);
+ while (_iter.MoveNext())
+ {
+ if (((XmlDiffNavigator)_iter.Current).CurrentNode is XmlDiffElement)
+ {
+ SortChildren((XmlDiffElement)((XmlDiffNavigator)_iter.Current).CurrentNode);
+ }
+ }
+ }
+
+ public void IgnoreNodes(XPathExpression expr)
+ {
+ if (expr == null)
+ {
+ return;
+ }
+ XPathNavigator _nav = this.CreateNavigator();
+ XPathNodeIterator _iter = _nav.Select(expr);
+ while (_iter.MoveNext())
+ {
+ if (((XmlDiffNavigator)_iter.Current).CurrentNode is XmlDiffAttribute)
+ {
+ ((XmlDiffElement)((XmlDiffNavigator)_iter.Current).CurrentNode.ParentNode).DeleteAttribute((XmlDiffAttribute)((XmlDiffNavigator)_iter.Current).CurrentNode);
+ }
+ else
+ {
+ ((XmlDiffNavigator)_iter.Current).CurrentNode.ParentNode.DeleteChild(((XmlDiffNavigator)_iter.Current).CurrentNode);
+ }
+ }
+ }
+
+ public void IgnoreValues(XPathExpression expr)
+ {
+ if (expr == null)
+ {
+ return;
+ }
+ XPathNavigator _nav = this.CreateNavigator();
+ XPathNodeIterator _iter = _nav.Select(expr);
+ while (_iter.MoveNext())
+ {
+ ((XmlDiffNavigator)_iter.Current).CurrentNode.IgnoreValue = true; ;
+ }
+ }
+
+ private void SortChildren(XmlDiffElement elem)
+ {
+ if (elem.FirstChild != null)
+ {
+ XmlDiffNode _first = elem.FirstChild;
+ XmlDiffNode _current = elem.FirstChild;
+ XmlDiffNode _last = elem.LastChild;
+ elem._firstChild = null;
+ elem._lastChild = null;
+ //set flag to ignore child order
+ bool temp = IgnoreChildOrder;
+ IgnoreChildOrder = true;
+ XmlDiffNode _next = null;
+ do
+ {
+ if (_current is XmlDiffElement)
+ _next = _current._next;
+ _current._next = null;
+ InsertChild(elem, _current);
+ if (_current == _last)
+ break;
+ _current = _next;
+ }
+ while (true);
+ //restore flag for ignoring child order
+ IgnoreChildOrder = temp;
+ }
+ }
+ }
+
+ //navgator over the xmldiffdocument
+ public class XmlDiffNavigator : XPathNavigator
+ {
+ private XmlDiffDocument _document;
+ private XmlDiffNode _currentNode;
+
+ public XmlDiffNavigator(XmlDiffDocument doc)
+ {
+ _document = doc;
+ _currentNode = _document;
+ }
+ public override XPathNavigator Clone()
+ {
+ XmlDiffNavigator _clone = new XmlDiffNavigator(_document);
+ if (!_clone.MoveTo(this))
+ throw new Exception("Cannot clone");
+ return _clone;
+ }
+ public override XmlNodeOrder ComparePosition(XPathNavigator nav)
+ {
+ XmlDiffNode targetNode = ((XmlDiffNavigator)nav).CurrentNode;
+ // Debug.Assert(false, "ComparePosition is NYI");
+ if (!(nav is XmlDiffNavigator))
+ {
+ return XmlNodeOrder.Unknown;
+ }
+ if (targetNode == this.CurrentNode)
+ {
+ return XmlNodeOrder.Same;
+ }
+ else
+ {
+ if (this.CurrentNode.ParentNode == null) //this is root
+ {
+ return XmlNodeOrder.After;
+ }
+ else if (targetNode.ParentNode == null) //this is root
+ {
+ return XmlNodeOrder.Before;
+ }
+ else //look in the following nodes
+ {
+ if (targetNode.LineNumber + targetNode.LinePosition > this.CurrentNode.LinePosition + this.CurrentNode.LineNumber)
+ {
+ return XmlNodeOrder.After;
+ }
+ return XmlNodeOrder.Before;
+ }
+ }
+ }
+ public override String GetAttribute(String localName, String namespaceURI)
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ return ((XmlDiffElement)_currentNode).GetAttributeValue(localName, namespaceURI);
+ }
+ return "";
+ }
+
+ public override String GetNamespace(String name)
+ {
+ Debug.Assert(false, "GetNamespace is NYI");
+ return "";
+ }
+
+ /*public override bool IsDescendant (XPathNavigator nav)
+ {
+ Debug.Assert(false, "IsDescendant is NYI");
+ return false;
+ }
+ */
+
+ public override bool IsSamePosition(XPathNavigator other)
+ {
+ if (other is XmlDiffNavigator)
+ {
+ if (_currentNode == ((XmlDiffNavigator)other).CurrentNode)
+ return true;
+ }
+ return false;
+ }
+
+ public override bool MoveTo(XPathNavigator other)
+ {
+ if (other is XmlDiffNavigator)
+ {
+ _currentNode = ((XmlDiffNavigator)other).CurrentNode;
+ return true;
+ }
+ return false;
+ }
+
+ public override bool MoveToAttribute(String localName, String namespaceURI)
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ XmlDiffAttribute _attr = ((XmlDiffElement)_currentNode).GetAttribute(localName, namespaceURI);
+ if (_attr != null)
+ {
+ _currentNode = _attr;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override bool MoveToFirst()
+ {
+ if (!(_currentNode is XmlDiffAttribute))
+ {
+ if (_currentNode.ParentNode.FirstChild == _currentNode)
+ {
+ if (_currentNode.ParentNode.FirstChild._next != null)
+ {
+ _currentNode = _currentNode.ParentNode.FirstChild._next;
+ return true;
+ }
+ }
+ else
+ {
+ _currentNode = _currentNode.ParentNode.FirstChild;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override bool MoveToFirstAttribute()
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ if (((XmlDiffElement)_currentNode).FirstAttribute != null)
+ {
+ XmlDiffAttribute _attr = ((XmlDiffElement)_currentNode).FirstAttribute;
+ while (_attr != null && IsNamespaceNode(_attr))
+ {
+ _attr = (XmlDiffAttribute)_attr._next;
+ }
+ if (_attr != null)
+ {
+ _currentNode = _attr;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public override bool MoveToFirstChild()
+ {
+ if ((_currentNode is XmlDiffDocument || _currentNode is XmlDiffElement) && _currentNode.FirstChild != null)
+ {
+ _currentNode = _currentNode.FirstChild;
+ return true;
+ }
+ return false;
+ }
+
+ //sunghonhack
+ public new bool MoveToFirstNamespace()
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ if (((XmlDiffElement)_currentNode).FirstAttribute != null)
+ {
+ XmlDiffAttribute _attr = ((XmlDiffElement)_currentNode).FirstAttribute;
+ while (_attr != null && !IsNamespaceNode(_attr))
+ {
+ _attr = (XmlDiffAttribute)_attr._next;
+ }
+ if (_attr != null)
+ {
+ _currentNode = _attr;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope)
+ {
+ return this.MoveToFirstNamespace();
+ }
+ public override bool MoveToId(String id)
+ {
+ Debug.Assert(false, "MoveToId is NYI");
+ return false;
+ }
+ public override bool MoveToNamespace(String name)
+ {
+ Debug.Assert(false, "MoveToNamespace is NYI");
+ return false;
+ }
+ public override bool MoveToNext()
+ {
+ if (!(_currentNode is XmlDiffAttribute) && _currentNode._next != null)
+ {
+ _currentNode = _currentNode._next;
+ return true;
+ }
+ return false;
+ }
+ public override bool MoveToNextAttribute()
+ {
+ if (_currentNode is XmlDiffAttribute)
+ {
+ XmlDiffAttribute _attr = (XmlDiffAttribute)_currentNode._next;
+ while (_attr != null && IsNamespaceNode(_attr))
+ {
+ _attr = (XmlDiffAttribute)_attr._next;
+ }
+ if (_attr != null)
+ {
+ _currentNode = _attr;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //sunghonhack
+ public new bool MoveToNextNamespace()
+ {
+ if (_currentNode is XmlDiffAttribute)
+ {
+ XmlDiffAttribute _attr = (XmlDiffAttribute)_currentNode._next;
+ while (_attr != null && !IsNamespaceNode(_attr))
+ {
+ _attr = (XmlDiffAttribute)_attr._next;
+ }
+ if (_attr != null)
+ {
+ _currentNode = _attr;
+ return true;
+ }
+ }
+ return false;
+ }
+ private bool IsNamespaceNode(XmlDiffAttribute attr)
+ {
+ return attr.LocalName.ToLower(System.Globalization.CultureInfo.InvariantCulture) == "xmlns" ||
+ attr.Prefix.ToLower(System.Globalization.CultureInfo.InvariantCulture) == "xmlns";
+ }
+ public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope)
+ {
+ return this.MoveToNextNamespace();
+ }
+ public override bool MoveToParent()
+ {
+ if (!(_currentNode is XmlDiffDocument))
+ {
+ _currentNode = _currentNode.ParentNode;
+ return true;
+ }
+ return false;
+ }
+ public override bool MoveToPrevious()
+ {
+ if (_currentNode != _currentNode.ParentNode.FirstChild)
+ {
+ XmlDiffNode _current = _currentNode.ParentNode.FirstChild;
+ XmlDiffNode _prev = _currentNode.ParentNode.FirstChild;
+ while (_current != _currentNode)
+ {
+ _prev = _current;
+ _current = _current._next;
+ }
+ _currentNode = _prev;
+ return true;
+ }
+ return false;
+ }
+ public override void MoveToRoot()
+ {
+ _currentNode = _document;
+ }
+
+ //properties
+
+ public override XPathNodeType NodeType
+ {
+ get
+ {
+ //namespace, comment and whitespace node types are not supported
+ switch (_currentNode.NodeType)
+ {
+ case XmlDiffNodeType.Element:
+ return XPathNodeType.Element;
+ case XmlDiffNodeType.Attribute:
+ return XPathNodeType.Attribute;
+ case XmlDiffNodeType.ER:
+ return XPathNodeType.Text;
+ case XmlDiffNodeType.Text:
+ return XPathNodeType.Text;
+ case XmlDiffNodeType.CData:
+ return XPathNodeType.Text;
+ case XmlDiffNodeType.Comment:
+ return XPathNodeType.Comment;
+ case XmlDiffNodeType.PI:
+ return XPathNodeType.ProcessingInstruction;
+ case XmlDiffNodeType.WS:
+ return XPathNodeType.SignificantWhitespace;
+ case XmlDiffNodeType.Document:
+ return XPathNodeType.Root;
+ default:
+ return XPathNodeType.All;
+ }
+ }
+ }
+
+ public override string LocalName
+ {
+ get
+ {
+ if (_currentNode.NodeType == XmlDiffNodeType.Element)
+ {
+ return ((XmlDiffElement)_currentNode).LocalName;
+ }
+ else if (_currentNode.NodeType == XmlDiffNodeType.Attribute)
+ {
+ return ((XmlDiffAttribute)_currentNode).LocalName;
+ }
+ else if (_currentNode.NodeType == XmlDiffNodeType.PI)
+ {
+ return ((XmlDiffProcessingInstruction)_currentNode).Name;
+ }
+ return "";
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ if (_currentNode.NodeType == XmlDiffNodeType.Element)
+ {
+ //return ((XmlDiffElement)m_currentNode).Name;
+ return _document.nameTable.Get(((XmlDiffElement)_currentNode).Name);
+ }
+ else if (_currentNode.NodeType == XmlDiffNodeType.Attribute)
+ {
+ return ((XmlDiffAttribute)_currentNode).Name;
+ }
+ else if (_currentNode.NodeType == XmlDiffNodeType.PI)
+ {
+ return ((XmlDiffProcessingInstruction)_currentNode).Name;
+ }
+ return "";
+ }
+ }
+
+ public override string NamespaceURI
+ {
+ get
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ return ((XmlDiffElement)_currentNode).NamespaceURI;
+ }
+ else if (_currentNode is XmlDiffAttribute)
+ {
+ return ((XmlDiffAttribute)_currentNode).NamespaceURI;
+ }
+ return "";
+ }
+ }
+
+ public override string Value
+ {
+ get
+ {
+ if (_currentNode is XmlDiffAttribute)
+ {
+ return ((XmlDiffAttribute)_currentNode).Value;
+ }
+ else if (_currentNode is XmlDiffCharacterData)
+ {
+ return ((XmlDiffCharacterData)_currentNode).Value;
+ }
+ else if (_currentNode is XmlDiffElement)
+ {
+ return ((XmlDiffElement)_currentNode).Value;
+ }
+ return "";
+ }
+ }
+
+ public override string Prefix
+ {
+ get
+ {
+ if (_currentNode is XmlDiffElement)
+ {
+ return ((XmlDiffElement)_currentNode).Prefix;
+ }
+ else if (_currentNode is XmlDiffAttribute)
+ {
+ return ((XmlDiffAttribute)_currentNode).Prefix;
+ }
+ return "";
+ }
+ }
+
+ public override string BaseURI
+ {
+ get
+ {
+ Debug.Assert(false, "BaseURI is NYI");
+ return "";
+ }
+ }
+ public override string XmlLang
+ {
+ get
+ {
+ Debug.Assert(false, "XmlLang not supported");
+ return "";
+ }
+ }
+ public override bool HasAttributes
+ {
+ get
+ {
+ return (_currentNode is XmlDiffElement && ((XmlDiffElement)_currentNode).FirstAttribute != null) ? true : false;
+ }
+ }
+ public override bool HasChildren
+ {
+ get
+ {
+ return _currentNode._next != null ? true : false;
+ }
+ }
+ public override bool IsEmptyElement
+ {
+ get
+ {
+ return _currentNode is XmlDiffEmptyElement ? true : false;
+ }
+ }
+ public override XmlNameTable NameTable
+ {
+ get
+ {
+ return _document.nameTable;
+ //return new NameTable();
+ }
+ }
+ public XmlDiffNode CurrentNode
+ {
+ get
+ {
+ return _currentNode;
+ }
+ }
+ public bool IsOnRoot()
+ {
+ return _currentNode == null ? true : false;
+ }
+ }
+
+
+
+ public class PropertyCollection : Hashtable { }
+
+ public abstract class XmlDiffNode
+ {
+ internal XmlDiffNode _next;
+ internal XmlDiffNode _firstChild;
+ internal XmlDiffNode _lastChild;
+ internal XmlDiffNode _parent;
+ internal int _lineNumber, _linePosition;
+ internal bool _bIgnoreValue;
+ private PropertyCollection _extendedProperties;
+
+ public XmlDiffNode()
+ {
+ this._next = null;
+ this._firstChild = null;
+ this._lastChild = null;
+ this._parent = null;
+ _lineNumber = 0;
+ _linePosition = 0;
+ }
+
+ public XmlDiffNode FirstChild
+ {
+ get
+ {
+ return this._firstChild;
+ }
+ }
+ public XmlDiffNode LastChild
+ {
+ get
+ {
+ return this._lastChild;
+ }
+ }
+ public XmlDiffNode NextSibling
+ {
+ get
+ {
+ return this._next;
+ }
+ }
+ public XmlDiffNode ParentNode
+ {
+ get
+ {
+ return this._parent;
+ }
+ }
+
+ public virtual bool IgnoreValue
+ {
+ get
+ {
+ return _bIgnoreValue;
+ }
+ set
+ {
+ _bIgnoreValue = value;
+ XmlDiffNode current = this._firstChild;
+ while (current != null)
+ {
+ current.IgnoreValue = value;
+ current = current._next;
+ }
+ }
+ }
+
+
+ public abstract XmlDiffNodeType NodeType { get; }
+
+ public virtual string OuterXml
+ {
+ get
+ {
+ StringWriter sw = new StringWriter();
+ XmlTextWriter xw = new XmlTextWriter(sw);
+
+ WriteTo(xw);
+ xw.Close();
+
+ return sw.ToString();
+ }
+ }
+ public virtual string InnerXml
+ {
+ get
+ {
+ StringWriter sw = new StringWriter();
+ XmlTextWriter xw = new XmlTextWriter(sw);
+
+ WriteContentTo(xw);
+ xw.Close();
+
+ return sw.ToString();
+ }
+ }
+
+ public abstract void WriteTo(XmlWriter w);
+ public abstract void WriteContentTo(XmlWriter w);
+
+ public PropertyCollection ExtendedProperties
+ {
+ get
+ {
+ if (_extendedProperties == null)
+ _extendedProperties = new PropertyCollection();
+ return _extendedProperties;
+ }
+ }
+ public virtual void InsertChildAfter(XmlDiffNode child, XmlDiffNode newChild)
+ {
+ Debug.Assert(newChild != null);
+ newChild._parent = this;
+ if (child == null)
+ {
+ newChild._next = this._firstChild;
+ this._firstChild = newChild;
+ }
+ else
+ {
+ Debug.Assert(child._parent == this);
+ newChild._next = child._next;
+ child._next = newChild;
+ }
+ if (newChild._next == null)
+ this._lastChild = newChild;
+ }
+
+ public virtual void DeleteChild(XmlDiffNode child)
+ {
+ if (child == this.FirstChild)//delete head
+ {
+ _firstChild = this.FirstChild.NextSibling;
+ }
+ else
+ {
+ XmlDiffNode current = this.FirstChild;
+ XmlDiffNode previous = null;
+ while (current != child)
+ {
+ previous = current;
+ current = current.NextSibling;
+ }
+ Debug.Assert(current != null);
+ if (current == this.LastChild) //tail being deleted
+ {
+ this._lastChild = current.NextSibling;
+ }
+ previous._next = current.NextSibling;
+ }
+ }
+
+ public int LineNumber
+ {
+ get { return this._lineNumber; }
+ set { this._lineNumber = value; }
+ }
+
+ public int LinePosition
+ {
+ get { return this._linePosition; }
+ set { this._linePosition = value; }
+ }
+ }
+
+ public class XmlDiffElement : XmlDiffNode
+ {
+ private string _lName;
+ private string _prefix;
+ private string _ns;
+ private XmlDiffAttribute _firstAttribute;
+ private XmlDiffAttribute _lastAttribute;
+ private int _attrC;
+ private int _endLineNumber, _endLinePosition;
+
+ public XmlDiffElement(string localName, string prefix, string ns)
+ : base()
+ {
+ _lName = localName;
+ _prefix = prefix;
+ _ns = ns;
+ _firstAttribute = null;
+ _lastAttribute = null;
+ _attrC = -1;
+ }
+
+ public override XmlDiffNodeType NodeType { get { return XmlDiffNodeType.Element; } }
+ public string LocalName { get { return _lName; } }
+ public string NamespaceURI { get { return _ns; } }
+ public string Prefix { get { return _prefix; } }
+
+ public string Name
+ {
+ get
+ {
+ if (_prefix.Length > 0)
+ return Prefix + ":" + LocalName;
+ else
+ return LocalName;
+ }
+ }
+
+ public XmlDiffAttribute FirstAttribute
+ {
+ get
+ {
+ return _firstAttribute;
+ }
+ }
+ public XmlDiffAttribute LastAttribute
+ {
+ get
+ {
+ return _lastAttribute;
+ }
+ }
+ public string GetAttributeValue(string LocalName, string NamespaceUri)
+ {
+ if (_firstAttribute != null)
+ {
+ XmlDiffAttribute _current = _firstAttribute;
+ do
+ {
+ if (_current.LocalName == LocalName && _current.NamespaceURI == NamespaceURI)
+ {
+ return _current.Value;
+ }
+ _current = (XmlDiffAttribute)_current._next;
+ }
+ while (_current != _lastAttribute);
+ }
+ return "";
+ }
+
+ public XmlDiffAttribute GetAttribute(string LocalName, string NamespaceUri)
+ {
+ if (_firstAttribute != null)
+ {
+ XmlDiffAttribute _current = _firstAttribute;
+ do
+ {
+ if (_current.LocalName == LocalName && _current.NamespaceURI == NamespaceURI)
+ {
+ return _current;
+ }
+ _current = (XmlDiffAttribute)_current._next;
+ }
+ while (_current != _lastAttribute);
+ }
+ return null;
+ }
+
+ internal void InsertAttributeAfter(XmlDiffAttribute attr, XmlDiffAttribute newAttr)
+ {
+ Debug.Assert(newAttr != null);
+ newAttr._ownerElement = this;
+ if (attr == null)
+ {
+ newAttr._next = _firstAttribute;
+ _firstAttribute = newAttr;
+ }
+ else
+ {
+ Debug.Assert(attr._ownerElement == this);
+ newAttr._next = attr._next;
+ attr._next = newAttr;
+ }
+ if (newAttr._next == null)
+ _lastAttribute = newAttr;
+ }
+
+ internal void DeleteAttribute(XmlDiffAttribute attr)
+ {
+ if (attr == this.FirstAttribute)//delete head
+ {
+ if (attr == this.LastAttribute) //tail being deleted
+ {
+ _lastAttribute = (XmlDiffAttribute)attr.NextSibling;
+ }
+ _firstAttribute = (XmlDiffAttribute)this.FirstAttribute.NextSibling;
+ }
+ else
+ {
+ XmlDiffAttribute current = this.FirstAttribute;
+ XmlDiffAttribute previous = null;
+ while (current != attr)
+ {
+ previous = current;
+ current = (XmlDiffAttribute)current.NextSibling;
+ }
+ Debug.Assert(current != null);
+ if (current == this.LastAttribute) //tail being deleted
+ {
+ _lastAttribute = (XmlDiffAttribute)current.NextSibling;
+ }
+ previous._next = current.NextSibling;
+ }
+ }
+
+ public int AttributeCount
+ {
+ get
+ {
+ if (_attrC != -1)
+ return _attrC;
+ XmlDiffAttribute attr = _firstAttribute;
+ _attrC = 0;
+ while (attr != null)
+ {
+ _attrC++;
+ attr = (XmlDiffAttribute)attr.NextSibling;
+ }
+ return _attrC;
+ }
+ }
+ public override bool IgnoreValue
+ {
+ set
+ {
+ base.IgnoreValue = value;
+ XmlDiffAttribute current = _firstAttribute;
+ while (current != null)
+ {
+ current.IgnoreValue = value;
+ current = (XmlDiffAttribute)current._next;
+ }
+ }
+ }
+
+ public int EndLineNumber
+ {
+ get { return _endLineNumber; }
+ set { _endLineNumber = value; }
+ }
+
+ public int EndLinePosition
+ {
+ get { return _endLinePosition; }
+ set { _endLinePosition = value; }
+ }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ w.WriteStartElement(Prefix, LocalName, NamespaceURI);
+ XmlDiffAttribute attr = _firstAttribute;
+ while (attr != null)
+ {
+ attr.WriteTo(w);
+ attr = (XmlDiffAttribute)(attr.NextSibling);
+ }
+ WriteContentTo(w);
+ w.WriteFullEndElement();
+ }
+
+ public override void WriteContentTo(XmlWriter w)
+ {
+ XmlDiffNode child = FirstChild;
+ while (child != null)
+ {
+ child.WriteTo(w);
+ child = child.NextSibling;
+ }
+ }
+
+ public string Value
+ {
+ get
+ {
+ if (this.IgnoreValue)
+ {
+ return "";
+ }
+ if (_firstChild != null)
+ {
+ StringBuilder _bldr = new StringBuilder();
+ XmlDiffNode _current = _firstChild;
+ do
+ {
+ if (_current is XmlDiffCharacterData && _current.NodeType != XmlDiffNodeType.Comment && _current.NodeType != XmlDiffNodeType.PI)
+ {
+ _bldr.Append(((XmlDiffCharacterData)_current).Value);
+ }
+ else if (_current is XmlDiffElement)
+ {
+ _bldr.Append(((XmlDiffElement)_current).Value);
+ }
+ _current = _current._next;
+ }
+ while (_current != null);
+ return _bldr.ToString();
+ }
+ return "";
+ }
+ }
+ }
+
+ public class XmlDiffEmptyElement : XmlDiffElement
+ {
+ public XmlDiffEmptyElement(string localName, string prefix, string ns) : base(localName, prefix, ns) { }
+ }
+
+ public class XmlDiffAttribute : XmlDiffNode
+ {
+ internal XmlDiffElement _ownerElement;
+ private string _lName;
+ private string _prefix;
+ private string _ns;
+ private string _value;
+ private XmlQualifiedName _valueAsQName;
+
+ public XmlDiffAttribute(string localName, string prefix, string ns, string value)
+ : base()
+ {
+ _lName = localName;
+ _prefix = prefix;
+ _ns = ns;
+ _value = value;
+ }
+
+ public string Value
+ {
+ get
+ {
+ if (this.IgnoreValue)
+ {
+ return "";
+ }
+ return _value;
+ }
+ }
+ public XmlQualifiedName ValueAsQName
+ {
+ get { return _valueAsQName; }
+ }
+
+ internal void SetValueAsQName(XmlReader reader, string value)
+ {
+ int indexOfColon = value.IndexOf(':');
+ if (indexOfColon == -1)
+ {
+ _valueAsQName = new XmlQualifiedName(value);
+ }
+ else
+ {
+ string prefix = value.Substring(0, indexOfColon);
+ string ns = reader.LookupNamespace(prefix);
+ if (ns == null)
+ {
+ _valueAsQName = null;
+ }
+ else
+ {
+ try
+ {
+ string localName = XmlConvert.VerifyNCName(value.Substring(indexOfColon + 1));
+ _valueAsQName = new XmlQualifiedName(localName, ns);
+ }
+ catch (XmlException)
+ {
+ _valueAsQName = null;
+ }
+ }
+ }
+ }
+
+ public string LocalName { get { return _lName; } }
+ public string NamespaceURI { get { return _ns; } }
+ public string Prefix { get { return _prefix; } }
+
+ public string Name
+ {
+ get
+ {
+ if (_prefix.Length > 0)
+ return _prefix + ":" + _lName;
+ else
+ return _lName;
+ }
+ }
+ public override XmlDiffNodeType NodeType { get { return XmlDiffNodeType.Attribute; } }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ w.WriteStartAttribute(Prefix, LocalName, NamespaceURI);
+ WriteContentTo(w);
+ w.WriteEndAttribute();
+ }
+
+ public override void WriteContentTo(XmlWriter w)
+ {
+ w.WriteString(Value);
+ }
+ }
+
+ public class XmlDiffEntityReference : XmlDiffNode
+ {
+ private string _name;
+ public XmlDiffEntityReference(string name)
+ : base()
+ {
+ _name = name;
+ }
+ public override XmlDiffNodeType NodeType { get { return XmlDiffNodeType.ER; } }
+ public string Name { get { return _name; } }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ w.WriteEntityRef(_name);
+ }
+
+ public override void WriteContentTo(XmlWriter w)
+ {
+ XmlDiffNode child = this.FirstChild;
+ while (child != null)
+ {
+ child.WriteTo(w);
+ child = child.NextSibling;
+ }
+ }
+ }
+
+ public class XmlDiffCharacterData : XmlDiffNode
+ {
+ private string _value;
+ private XmlDiffNodeType _nodetype;
+ public XmlDiffCharacterData(string value, XmlDiffNodeType nt, bool NormalizeNewline)
+ : base()
+ {
+ _value = value;
+ if (NormalizeNewline)
+ {
+ _value = _value.Replace("\n", "");
+ _value = _value.Replace("\r", "");
+ }
+ _nodetype = nt;
+ }
+
+ public string Value
+ {
+ get
+ {
+ if (this.IgnoreValue)
+ {
+ return "";
+ }
+ return _value;
+ }
+ set
+ {
+ _value = value;
+ }
+ }
+ public override XmlDiffNodeType NodeType { get { return _nodetype; } }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ switch (_nodetype)
+ {
+ case XmlDiffNodeType.Comment:
+ w.WriteComment(Value);
+ break;
+ case XmlDiffNodeType.CData:
+ w.WriteCData(Value);
+ break;
+ case XmlDiffNodeType.WS:
+ case XmlDiffNodeType.Text:
+ w.WriteString(Value);
+ break;
+ default:
+ Debug.Assert(false, "Wrong type for text-like node : " + _nodetype.ToString());
+ break;
+ }
+ }
+
+ public override void WriteContentTo(XmlWriter w) { }
+ }
+
+ public class XmlDiffProcessingInstruction : XmlDiffCharacterData
+ {
+ private string _name;
+ public XmlDiffProcessingInstruction(string name, string value)
+ : base(value, XmlDiffNodeType.PI, false)
+ {
+ _name = name;
+ }
+ public string Name { get { return _name; } }
+
+ public override void WriteTo(XmlWriter w)
+ {
+ w.WriteProcessingInstruction(_name, Value);
+ }
+ public override void WriteContentTo(XmlWriter w) { }
+ }
+}
--- /dev/null
+using System.Collections.Generic;
+
+namespace System.ServiceModel.Syndication.Tests
+{
+ [Flags]
+ public enum XmlDiffOption
+ {
+ None = 0x0,
+ IgnoreEmptyElement = 0x1,
+ IgnoreWhitespace = 0x2,
+ IgnoreComments = 0x4,
+ IgnoreAttributeOrder = 0x8,
+ IgnoreNS = 0x10,
+ IgnorePrefix = 0x20,
+ IgnoreDTD = 0x40,
+ IgnoreChildOrder = 0x80,
+ InfosetComparison = 0xB, //sets IgnoreEmptyElement, IgnoreWhitespace and IgnoreAttributeOrder
+ CDataAsText = 0x100,
+ NormalizeNewline = 0x200, // ignores newlines in text nodes only
+ ConcatenateAdjacentTextNodes = 0x400, // treats adjacent text nodes as a single node
+ TreatWhitespaceTextAsWSNode = 0x800, // if a text node contains only whitespaces, it will be considered a whitespace node
+ ParseAttributeValuesAsQName = 0x1000, // <a xmlns:p1="n1" t="p1:foo"/> will be treated the same as <a xmlns:p2="n1" t="p2:foo"/>
+ DontWriteMatchingNodesToOutput = 0x2000, // output will only contain different nodes
+ DontWriteAnythingToOutput = 0x4000, // output will not contain anything (needed for very large XML docs, which could trigger OOM)
+ IgnoreEmptyTextNodes = 0x8000, // empty text nodes (sometimes produced by the binary reader) are ignored
+ WhitespaceAsText = 0x10000, // consider whitespace nodes as text nodes
+ }
+
+ public class XmlDiffAdvancedOptions
+ {
+ private string _ignoreNodesExpr;
+ private string _ignoreValuesExpr;
+ private string _ignoreChildOrderExpr;
+ private IDictionary<string, string> _addedNamespaces;
+
+ public XmlDiffAdvancedOptions()
+ {
+ _addedNamespaces = new Dictionary<string, string>();
+ }
+
+ public string IgnoreNodesExpr
+ {
+ get
+ {
+ return _ignoreNodesExpr;
+ }
+ set
+ {
+ _ignoreNodesExpr = value;
+ }
+ }
+
+ public string IgnoreValuesExpr
+ {
+ get
+ {
+ return _ignoreValuesExpr;
+ }
+ set
+ {
+ _ignoreValuesExpr = value;
+ }
+ }
+
+ public string IgnoreChildOrderExpr
+ {
+ get
+ {
+ return _ignoreChildOrderExpr;
+ }
+ set
+ {
+ _ignoreChildOrderExpr = value;
+ }
+ }
+
+ public void AddNamespace(string prefix, string uri)
+ {
+ _addedNamespaces[prefix] = uri;
+ }
+
+ public bool HadAddedNamespace()
+ {
+ return 0 != _addedNamespaces.Count;
+ }
+
+ public IDictionary<string, string> AddedNamespaces
+ {
+ get { return _addedNamespaces; }
+ }
+ }
+}