Repository: tafia/quick-xml
Pull request #407 (2022-06-29 00:54:58)

Improve benchmark suite

codecov-commenter: # [Codecov](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#407](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (b22caee) into [master](https://codecov.io/gh/tafia/quick-xml/commit/f6d5e99e039f3a8d14b0d6a098314246dba3f51a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (f6d5e99) will **decrease** coverage by `0.04%`.
> The diff coverage is `n/a`.

> :exclamation: Current head b22caee differs from pull request most recent head d9abcb8. Consider uploading reports for the commit d9abcb8 to get more accurate results

```diff
@@            Coverage Diff             @@
##           master     #407      +/-   ##
==========================================
- Coverage   63.84%   63.80%   -0.05%     
==========================================
  Files          20       20              
  Lines       10870    10873       +3     
==========================================
- Hits         6940     6937       -3     
- Misses       3930     3936       +6     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `63.80% <ø> (-0.05%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [src/de/map.rs](https://codecov.io/gh/tafia/quick-xml/pull/407/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2RlL21hcC5ycw==) | `72.85% <0.00%> (-0.46%)` | :arrow_down: |
| [src/lib.rs](https://codecov.io/gh/tafia/quick-xml/pull/407/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2xpYi5ycw==) | `21.23% <0.00%> (-0.16%)` | :arrow_down: |
| [src/reader.rs](https://codecov.io/gh/tafia/quick-xml/pull/407/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL3JlYWRlci5ycw==) | `89.00% <0.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Last update [f6d5e99...d9abcb8](https://codecov.io/gh/tafia/quick-xml/pull/407?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

dralley: Benchmarks compile but one of the original ones is still / re- broken

Patch:
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index e8f1d13..1f4869b 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -3,7 +3,14 @@ name: Rust
 on: [push, pull_request]
 
 jobs:
-  build:
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    - name: Check fmt
+      run: cargo fmt -- --check
+
+  test:
     strategy:
       matrix:
         platform: [ubuntu-latest, windows-latest]
@@ -15,13 +22,14 @@ jobs:
       RUSTFLAGS: -C instrument-coverage
 
     steps:
+    - uses: actions/checkout@v3
     - name: Install coverage reporter (llvm-tools-preview)
       if: runner.os == 'Linux'
       run: rustup component add llvm-tools-preview
     - name: Install coverage reporter (grcov)
       if: runner.os == 'Linux'
       run: cargo install grcov
-    - uses: actions/checkout@v1
+
     - name: Build
       run: cargo build
     - name: Build benchmarks
@@ -29,6 +37,9 @@ jobs:
     - name: Build benchmarks (compare)
       working-directory: compare
       run: cargo bench --no-run
+    - name: Run tests + benchmarks
+      run: cargo test --all-features --benches --tests
+
     - name: Run tests (no features)
       env:
         LLVM_PROFILE_FILE: coverage/no-features-%p-%m.profraw
@@ -67,6 +78,4 @@ jobs:
         flags: unittests
         verbose: true
       continue-on-error: true
-    - name: Check fmt
-      run: cargo fmt -- --check
 
diff --git a/Changelog.md b/Changelog.md
index 1e89efe..60b2b96 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -103,6 +103,7 @@
 - [#393]: Added more tests for namespace resolver
 - [#393]: Added tests for reserved names (started with "xml"i) -- see <https://www.w3.org/TR/xml-names11/#xmlReserved>
 - [#363]: Add tests for `Reader::read_event_buffered` to ensure that proper events generated for corresponding inputs
+- [#407]: Improved benchmark suite to cover whole-document parsing, escaping and unescaping text
 
 [#8]: https://github.com/Mingun/fast-xml/pull/8
 [#9]: https://github.com/Mingun/fast-xml/pull/9
@@ -115,6 +116,7 @@
 [#393]: https://github.com/tafia/quick-xml/pull/393
 [#395]: https://github.com/tafia/quick-xml/pull/395
 [#403]: https://github.com/tafia/quick-xml/pull/403
+[#407]: https://github.com/tafia/quick-xml/pull/407
 
 ## 0.23.0 -- 2022-05-08
 
diff --git a/benches/bench.rs b/benches/bench.rs
index 4f4b7c2..e4168ce 100644
--- a/benches/bench.rs
+++ b/benches/bench.rs
@@ -1,344 +1,6 @@
-use criterion::{self, criterion_group, criterion_main, Criterion};
-use pretty_assertions::assert_eq;
-use quick_xml::events::Event;
-use quick_xml::name::QName;
-use quick_xml::Reader;
+use criterion::criterion_main;
 
-static SAMPLE: &[u8] = include_bytes!("../tests/sample_rss.xml");
-static PLAYERS: &[u8] = include_bytes!("../tests/players.xml");
+mod macrobenches;
+mod microbenches;
 
-/// Benchmarks the `Reader::read_event` function with all XML well-formless
-/// checks disabled (with and without trimming content of #text nodes)
-fn read_event(c: &mut Criterion) {
-    let mut group = c.benchmark_group("read_event");
-    group.bench_function("trim_text = false", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-        })
-    });
-
-    group.bench_function("trim_text = true", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-        });
-    });
-    group.finish();
-}
-
-/// Benchmarks the `Reader::read_namespaced_event` function with all XML well-formless
-/// checks disabled (with and without trimming content of #text nodes)
-fn read_namespaced_event(c: &mut Criterion) {
-    let mut group = c.benchmark_group("read_namespaced_event");
-    group.bench_function("trim_text = false", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            let mut ns_buf = Vec::new();
-            loop {
-                match r.read_namespaced_event(&mut buf, &mut ns_buf) {
-                    Ok((_, Event::Start(_))) | Ok((_, Event::Empty(_))) => count += 1,
-                    Ok((_, Event::Eof)) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-        });
-    });
-
-    group.bench_function("trim_text = true", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            let mut ns_buf = Vec::new();
-            loop {
-                match r.read_namespaced_event(&mut buf, &mut ns_buf) {
-                    Ok((_, Event::Start(_))) | Ok((_, Event::Empty(_))) => count += 1,
-                    Ok((_, Event::Eof)) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-        });
-    });
-    group.finish();
-}
-
-/// Benchmarks the `BytesText::unescaped()` method (includes time of `read_event`
-/// benchmark)
-fn bytes_text_unescaped(c: &mut Criterion) {
-    let mut group = c.benchmark_group("BytesText::unescaped");
-    group.bench_function("trim_text = false", |b| {
-        b.iter(|| {
-            let mut buf = Vec::new();
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut nbtxt = criterion::black_box(0);
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
-                    Ok(Event::Text(ref e)) => nbtxt += e.unescaped().unwrap().len(),
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-
-            // Windows has \r\n instead of \n
-            #[cfg(windows)]
-            assert_eq!(
-                nbtxt, 67661,
-                "Overall length (in bytes) of all text contents of ./tests/sample_rss.xml"
-            );
-
-            #[cfg(not(windows))]
-            assert_eq!(
-                nbtxt, 66277,
-                "Overall length (in bytes) of all text contents of ./tests/sample_rss.xml"
-            );
-        });
-    });
-
-    group.bench_function("trim_text = true", |b| {
-        b.iter(|| {
-            let mut buf = Vec::new();
-            let mut r = Reader::from_reader(SAMPLE);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            let mut count = criterion::black_box(0);
-            let mut nbtxt = criterion::black_box(0);
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
-                    Ok(Event::Text(ref e)) => nbtxt += e.unescaped().unwrap().len(),
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
-
-            // Windows has \r\n instead of \n
-            #[cfg(windows)]
-            assert_eq!(
-                nbtxt, 50334,
-                "Overall length (in bytes) of all text contents of ./tests/sample_rss.xml"
-            );
-
-            #[cfg(not(windows))]
-            assert_eq!(
-                nbtxt, 50261,
-                "Overall length (in bytes) of all text contents of ./tests/sample_rss.xml"
-            );
-        });
-    });
-    group.finish();
-}
-
-/// Benchmarks, how fast individual event parsed
-fn one_event(c: &mut Criterion) {
-    let mut group = c.benchmark_group("One event");
-    group.bench_function("StartText", |b| {
-        let src = "Hello world!".repeat(512 / 12).into_bytes();
-        let mut buf = Vec::with_capacity(1024);
-        b.iter(|| {
-            let mut r = Reader::from_reader(src.as_ref());
-            let mut nbtxt = criterion::black_box(0);
-            r.check_end_names(false).check_comments(false);
-            match r.read_event(&mut buf) {
-                Ok(Event::StartText(e)) => nbtxt += e.unescaped().unwrap().len(),
-                something_else => panic!("Did not expect {:?}", something_else),
-            };
-
-            buf.clear();
-
-            assert_eq!(nbtxt, 504);
-        })
-    });
-
-    group.bench_function("Start", |b| {
-        let src = format!(r#"<hello target="{}">"#, "world".repeat(512 / 5)).into_bytes();
-        let mut buf = Vec::with_capacity(1024);
-        b.iter(|| {
-            let mut r = Reader::from_reader(src.as_ref());
-            let mut nbtxt = criterion::black_box(0);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            match r.read_event(&mut buf) {
-                Ok(Event::Start(ref e)) => nbtxt += e.len(),
-                something_else => panic!("Did not expect {:?}", something_else),
-            };
-
-            buf.clear();
-
-            assert_eq!(nbtxt, 525);
-        })
-    });
-
-    group.bench_function("Comment", |b| {
-        let src = format!(r#"<!-- hello "{}" -->"#, "world".repeat(512 / 5)).into_bytes();
-        let mut buf = Vec::with_capacity(1024);
-        b.iter(|| {
-            let mut r = Reader::from_reader(src.as_ref());
-            let mut nbtxt = criterion::black_box(0);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            match r.read_event(&mut buf) {
-                Ok(Event::Comment(ref e)) => nbtxt += e.unescaped().unwrap().len(),
-                something_else => panic!("Did not expect {:?}", something_else),
-            };
-
-            buf.clear();
-
-            assert_eq!(nbtxt, 520);
-        })
-    });
-
-    group.bench_function("CData", |b| {
-        let src = format!(r#"<![CDATA[hello "{}"]]>"#, "world".repeat(512 / 5)).into_bytes();
-        let mut buf = Vec::with_capacity(1024);
-        b.iter(|| {
-            let mut r = Reader::from_reader(src.as_ref());
-            let mut nbtxt = criterion::black_box(0);
-            r.check_end_names(false)
-                .check_comments(false)
-                .trim_text(true);
-            match r.read_event(&mut buf) {
-                Ok(Event::CData(ref e)) => nbtxt += e.len(),
-                something_else => panic!("Did not expect {:?}", something_else),
-            };
-
-            buf.clear();
-
-            assert_eq!(nbtxt, 518);
-        })
-    });
-    group.finish();
-}
-
-/// Benchmarks parsing attributes from events
-fn attributes(c: &mut Criterion) {
-    let mut group = c.benchmark_group("attributes");
-    group.bench_function("with_checks = true", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(PLAYERS);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Empty(e)) => {
-                        for attr in e.attributes() {
-                            let _attr = attr.unwrap();
-                            count += 1
-                        }
-                    }
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1041);
-        })
-    });
-
-    group.bench_function("with_checks = false", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(PLAYERS);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Empty(e)) => {
-                        for attr in e.attributes().with_checks(false) {
-                            let _attr = attr.unwrap();
-                            count += 1
-                        }
-                    }
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 1041);
-        })
-    });
-
-    group.bench_function("try_get_attribute", |b| {
-        b.iter(|| {
-            let mut r = Reader::from_reader(PLAYERS);
-            r.check_end_names(false).check_comments(false);
-            let mut count = criterion::black_box(0);
-            let mut buf = Vec::new();
-            loop {
-                match r.read_event(&mut buf) {
-                    Ok(Event::Empty(e)) if e.name() == QName(b"player") => {
-                        for name in ["num", "status", "avg"] {
-                            if let Some(_attr) = e.try_get_attribute(name).unwrap() {
-                                count += 1
-                            }
-                        }
-                        assert!(e
-                            .try_get_attribute("attribute-that-doesn't-exist")
-                            .unwrap()
-                            .is_none());
-                    }
-                    Ok(Event::Eof) => break,
-                    _ => (),
-                }
-                buf.clear();
-            }
-            assert_eq!(count, 150);
-        })
-    });
-    group.finish();
-}
-
-criterion_group!(
-    benches,
-    read_event,
-    bytes_text_unescaped,
-    read_namespaced_event,
-    one_event,
-    attributes
-);
-criterion_main!(benches);
+criterion_main!(macrobenches::benches, microbenches::benches);
diff --git a/benches/macrobenches.rs b/benches/macrobenches.rs
new file mode 100644
index 0000000..14f28cb
--- /dev/null
+++ b/benches/macrobenches.rs
@@ -0,0 +1,134 @@
+use criterion::{self, criterion_group, Criterion};
+use quick_xml::events::Event;
+use quick_xml::Reader;
+use quick_xml::Result as XmlResult;
+
+static RPM_PRIMARY: &[u8] = include_bytes!("../tests/documents/rpm_primary.xml");
+static RPM_PRIMARY2: &[u8] = include_bytes!("../tests/documents/rpm_primary2.xml");
+static RPM_FILELISTS: &[u8] = include_bytes!("../tests/documents/rpm_filelists.xml");
+static RPM_OTHER: &[u8] = include_bytes!("../tests/documents/rpm_other.xml");
+static LIBREOFFICE_DOCUMENT: &[u8] = include_bytes!("../tests/documents/libreoffice_document.fodt");
+static DOCUMENT: &[u8] = include_bytes!("../tests/documents/document.xml");
+static TEST_WRITER_INDENT: &[u8] = include_bytes!("../tests/documents/test_writer_indent.xml");
+static SAMPLE_1: &[u8] = include_bytes!("../tests/documents/sample_1.xml");
+static LINESCORE: &[u8] = include_bytes!("../tests/documents/linescore.xml");
+static SAMPLE_RSS: &[u8] = include_bytes!("../tests/documents/sample_rss.xml");
+static SAMPLE_NS: &[u8] = include_bytes!("../tests/documents/sample_ns.xml");
+static PLAYERS: &[u8] = include_bytes!("../tests/documents/players.xml");
+
+// TODO: read the namespaces too
+// TODO: use fully normalized attribute values
+fn parse_document(doc: &[u8]) -> XmlResult<()> {
+    let mut r = Reader::from_reader(doc);
+    loop {
+        match r.read_event_unbuffered()? {
+            Event::Start(e) | Event::Empty(e) => {
+                for attr in e.attributes() {
+                    criterion::black_box(attr?.unescaped_value()?);
+                }
+            }
+            Event::Text(e) => {
+                criterion::black_box(e.unescaped()?);
+            }
+            Event::CData(e) => {
+                criterion::black_box(e.into_inner());
+            }
+            Event::End(_) => (),
+            Event::Eof => break,
+            _ => (),
+        }
+    }
+    Ok(())
+}
+
+pub fn bench_fully_parse_document(c: &mut Criterion) {
+    let mut group = c.benchmark_group("fully_parse_document");
+
+    // long, mix of attributes and text, not much escaping, mix of attribute lengths, some namespaces
+    group.bench_function("rpm_primary.xml", |b| {
+        b.iter(|| {
+            parse_document(RPM_PRIMARY).unwrap();
+        })
+    });
+
+    // long, mix of attributes and text, not much escaping, mix of attribute lengths, some namespaces
+    group.bench_function("rpm_primary2.xml", |b| {
+        b.iter(|| {
+            parse_document(RPM_PRIMARY2).unwrap();
+        })
+    });
+
+    // long, mostly medium-length text elements, not much escaping
+    group.bench_function("rpm_filelists.xml", |b| {
+        b.iter(|| {
+            parse_document(RPM_FILELISTS).unwrap();
+        })
+    });
+
+    // long, mix of attributes and text, lots of escaping (both entity and char literal), long attributes
+    group.bench_function("rpm_other.xml", |b| {
+        b.iter(|| {
+            parse_document(RPM_OTHER).unwrap();
+        })
+    });
+
+    // long, mix of attributes and text, not much escaping, lots of non-ascii characters, lots of namespaces
+    group.bench_function("libreoffice_document.fodt", |b| {
+        b.iter(|| {
+            parse_document(LIBREOFFICE_DOCUMENT).unwrap();
+        })
+    });
+
+    // medium length, mostly empty tags, a few short attributes per element, no escaping
+    group.bench_function("document.xml", |b| {
+        b.iter(|| {
+            parse_document(DOCUMENT).unwrap();
+        })
+    });
+
+    // medium length, lots of namespaces, no escaping
+    group.bench_function("test_writer_ident.xml", |b| {
+        b.iter(|| {
+            parse_document(TEST_WRITER_INDENT).unwrap();
+        })
+    });
+
+    // short, mix of attributes and text, lots of escapes
+    group.bench_function("sample_1.xml", |b| {
+        b.iter(|| {
+            parse_document(SAMPLE_1).unwrap();
+        })
+    });
+
+    // medium length, lots of attributes, short attributes, few escapes
+    group.bench_function("linescore.xml", |b| {
+        b.iter(|| {
+            parse_document(LINESCORE).unwrap();
+        })
+    });
+
+    // short, lots of namespaces, no escapes
+    group.bench_function("sample_ns.xml", |b| {
+        b.iter(|| {
+            parse_document(SAMPLE_NS).unwrap();
+        })
+    });
+
+    // long, few attributes, mix of attribute lengths, escapes in text content
+    group.bench_function("sample_rss.xml", |b| {
+        b.iter(|| {
+            parse_document(SAMPLE_RSS).unwrap();
+        })
+    });
+
+    // long, lots of attributes, short attributes, no text, no escapes
+    group.bench_function("players.xml", |b| {
+        b.iter(|| {
+            parse_document(PLAYERS).unwrap();
+        })
+    });
+
+    group.finish();
+}
+
+criterion_group!(benches, bench_fully_parse_document,);
diff --git a/benches/microbenches.rs b/benches/microbenches.rs
new file mode 100644
index 0000000..9d701c0
--- /dev/null
+++ b/benches/microbenches.rs
@@ -0,0 +1,482 @@
+use criterion::{self, criterion_group, Criterion};
+use pretty_assertions::assert_eq;
+use quick_xml::escape::{escape, unescape};
+use quick_xml::events::Event;
+use quick_xml::name::QName;
+use quick_xml::Reader;
+
+static SAMPLE: &[u8] = include_bytes!("../tests/documents/sample_rss.xml");
+static PLAYERS: &[u8] = include_bytes!("../tests/documents/players.xml");
+
+static LOREM_IPSUM_TEXT: &[u8] =
+b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ut labore et dolore magna aliqua. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque.
+Risus ultricies tristique nulla aliquet enim tortor at. Fermentum odio eu feugiat pretium nibh ipsum.
+Volutpat sed cras ornare arcu dui. Scelerisque fermentum dui faucibus in ornare quam. Arcu cursus
+euismod quis viverra nibh cras pulvinar mattis. Sed viverra tellus in hac habitasse platea. Quis
+commodo odio aenean sed. Cursus in hac habitasse platea dictumst quisque sagittis purus.
+
+Neque convallis a cras semper auctor. Sit amet mauris commodo quis imperdiet massa. Ac ut consequat
+semper viverra nam libero justo laoreet sit. Adipiscing commodo elit at imperdiet dui accumsan.
+Enim lobortis scelerisque fermentum dui faucibus in ornare. Natoque penatibus et magnis dis parturient
+montes nascetur ridiculus mus. At lectus urna duis convallis convallis tellus id interdum. Libero
+volutpat sed cras ornare arcu dui vivamus arcu. Cursus in hac habitasse platea dictumst quisque sagittis
+purus. Consequat id porta nibh venenatis cras sed felis.";
+
+/// Benchmarks the `Reader::read_event` function with all XML well-formless
+/// checks disabled (with and without trimming content of #text nodes)
+fn read_event(c: &mut Criterion) {
+    let mut group = c.benchmark_group("read_event");
+    group.bench_function("trim_text = false", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+        })
+    });
+
+    group.bench_function("trim_text = true", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+        });
+    });
+    group.finish();
+}
+
+/// Benchmarks the `Reader::read_namespaced_event` function with all XML well-formless
+/// checks disabled (with and without trimming content of #text nodes)
+fn read_namespaced_event(c: &mut Criterion) {
+    let mut group = c.benchmark_group("read_namespaced_event");
+    group.bench_function("trim_text = false", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            let mut ns_buf = Vec::new();
+            loop {
+                match r.read_namespaced_event(&mut buf, &mut ns_buf) {
+                    Ok((_, Event::Start(_))) | Ok((_, Event::Empty(_))) => count += 1,
+                    Ok((_, Event::Eof)) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+        });
+    });
+
+    group.bench_function("trim_text = true", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            let mut ns_buf = Vec::new();
+            loop {
+                match r.read_namespaced_event(&mut buf, &mut ns_buf) {
+                    Ok((_, Event::Start(_))) | Ok((_, Event::Empty(_))) => count += 1,
+                    Ok((_, Event::Eof)) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+        });
+    });
+    group.finish();
+}
+
+/// Benchmarks the `BytesText::unescaped()` method (includes time of `read_event`
+/// benchmark)
+fn bytes_text_unescaped(c: &mut Criterion) {
+    let mut group = c.benchmark_group("BytesText::unescaped");
+    group.bench_function("trim_text = false", |b| {
+        b.iter(|| {
+            let mut buf = Vec::new();
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut nbtxt = criterion::black_box(0);
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
+                    Ok(Event::Text(ref e)) => nbtxt += e.unescaped().unwrap().len(),
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+
+            // Windows has \r\n instead of \n
+            #[cfg(windows)]
+            assert_eq!(
+                nbtxt, 67661,
+                "Overall length (in bytes) of all text contents of ./tests/documents/sample_rss.xml"
+            );
+
+            #[cfg(not(windows))]
+            assert_eq!(
+                nbtxt, 66277,
+                "Overall length (in bytes) of all text contents of ./tests/documents/sample_rss.xml"
+            );
+        });
+    });
+
+    group.bench_function("trim_text = true", |b| {
+        b.iter(|| {
+            let mut buf = Vec::new();
+            let mut r = Reader::from_reader(SAMPLE);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            let mut count = criterion::black_box(0);
+            let mut nbtxt = criterion::black_box(0);
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Start(_)) | Ok(Event::Empty(_)) => count += 1,
+                    Ok(Event::Text(ref e)) => nbtxt += e.unescaped().unwrap().len(),
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(
+                count, 1550,
+                "Overall tag count in ./tests/documents/sample_rss.xml"
+            );
+
+            // Windows has \r\n instead of \n
+            #[cfg(windows)]
+            assert_eq!(
+                nbtxt, 50334,
+                "Overall length (in bytes) of all text contents of ./tests/documents/sample_rss.xml"
+            );
+
+            #[cfg(not(windows))]
+            assert_eq!(
+                nbtxt, 50261,
+                "Overall length (in bytes) of all text contents of ./tests/documents/sample_rss.xml"
+            );
+        });
+    });
+    group.finish();
+}
+
+/// Benchmarks, how fast individual event parsed
+fn one_event(c: &mut Criterion) {
+    let mut group = c.benchmark_group("One event");
+    group.bench_function("StartText", |b| {
+        let src = "Hello world!".repeat(512 / 12).into_bytes();
+        let mut buf = Vec::with_capacity(1024);
+        b.iter(|| {
+            let mut r = Reader::from_reader(src.as_ref());
+            let mut nbtxt = criterion::black_box(0);
+            r.check_end_names(false).check_comments(false);
+            match r.read_event(&mut buf) {
+                Ok(Event::StartText(e)) => nbtxt += e.len(),
+                something_else => panic!("Did not expect {:?}", something_else),
+            };
+
+            buf.clear();
+
+            assert_eq!(nbtxt, 504);
+        })
+    });
+
+    group.bench_function("Start", |b| {
+        let src = format!(r#"<hello target="{}">"#, "world".repeat(512 / 5)).into_bytes();
+        let mut buf = Vec::with_capacity(1024);
+        b.iter(|| {
+            let mut r = Reader::from_reader(src.as_ref());
+            let mut nbtxt = criterion::black_box(0);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            match r.read_event(&mut buf) {
+                Ok(Event::Start(ref e)) => nbtxt += e.len(),
+                something_else => panic!("Did not expect {:?}", something_else),
+            };
+
+            buf.clear();
+
+            assert_eq!(nbtxt, 525);
+        })
+    });
+
+    group.bench_function("Comment", |b| {
+        let src = format!(r#"<!-- hello "{}" -->"#, "world".repeat(512 / 5)).into_bytes();
+        let mut buf = Vec::with_capacity(1024);
+        b.iter(|| {
+            let mut r = Reader::from_reader(src.as_ref());
+            let mut nbtxt = criterion::black_box(0);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            match r.read_event(&mut buf) {
+                Ok(Event::Comment(ref e)) => nbtxt += e.unescaped().unwrap().len(),
+                something_else => panic!("Did not expect {:?}", something_else),
+            };
+
+            buf.clear();
+
+            assert_eq!(nbtxt, 520);
+        })
+    });
+
+    group.bench_function("CData", |b| {
+        let src = format!(r#"<![CDATA[hello "{}"]]>"#, "world".repeat(512 / 5)).into_bytes();
+        let mut buf = Vec::with_capacity(1024);
+        b.iter(|| {
+            let mut r = Reader::from_reader(src.as_ref());
+            let mut nbtxt = criterion::black_box(0);
+            r.check_end_names(false)
+                .check_comments(false)
+                .trim_text(true);
+            match r.read_event(&mut buf) {
+                Ok(Event::CData(ref e)) => nbtxt += e.len(),
+                something_else => panic!("Did not expect {:?}", something_else),
+            };
+
+            buf.clear();
+
+            assert_eq!(nbtxt, 518);
+        })
+    });
+    group.finish();
+}
+
+/// Benchmarks parsing attributes from events
+fn attributes(c: &mut Criterion) {
+    let mut group = c.benchmark_group("attributes");
+    group.bench_function("with_checks = true", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(PLAYERS);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Empty(e)) => {
+                        for attr in e.attributes() {
+                            let _attr = attr.unwrap();
+                            count += 1
+                        }
+                    }
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(count, 1041);
+        })
+    });
+
+    group.bench_function("with_checks = false", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(PLAYERS);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Empty(e)) => {
+                        for attr in e.attributes().with_checks(false) {
+                            let _attr = attr.unwrap();
+                            count += 1
+                        }
+                    }
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(count, 1041);
+        })
+    });
+
+    group.bench_function("try_get_attribute", |b| {
+        b.iter(|| {
+            let mut r = Reader::from_reader(PLAYERS);
+            r.check_end_names(false).check_comments(false);
+            let mut count = criterion::black_box(0);
+            let mut buf = Vec::new();
+            loop {
+                match r.read_event(&mut buf) {
+                    Ok(Event::Empty(e)) if e.name() == QName(b"player") => {
+                        for name in ["num", "status", "avg"] {
+                            if let Some(_attr) = e.try_get_attribute(name).unwrap() {
+                                count += 1
+                            }
+                        }
+                        assert!(e
+                            .try_get_attribute("attribute-that-doesn't-exist")
+                            .unwrap()
+                            .is_none());
+                    }
+                    Ok(Event::Eof) => break,
+                    _ => (),
+                }
+                buf.clear();
+            }
+            assert_eq!(count, 150);
+        })
+    });
+    group.finish();
+}
+
+/// Benchmarks escaping text using XML rules
+fn escaping(c: &mut Criterion) {
+    let mut group = c.benchmark_group("escape_text");
+
+    group.bench_function("no_chars_to_escape_long", |b| {
+        b.iter(|| {
+            criterion::black_box(escape(LOREM_IPSUM_TEXT));
+        })
+    });
+
+    group.bench_function("no_chars_to_escape_short", |b| {
+        b.iter(|| {
+            criterion::black_box(escape(b"just bit of text"));
+        })
+    });
+
+    group.bench_function("escaped_chars_short", |b| {
+        b.iter(|| {
+            criterion::black_box(escape(b"age > 72 && age < 21"));
+            criterion::black_box(escape(b"\"what's that?\""));
+        })
+    });
+
+    group.bench_function("escaped_chars_long", |b| {
+        let lorem_ipsum_with_escape_chars =
+b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ut labore et dolore magna aliqua. & Hac habitasse platea dictumst vestibulum rhoncus est pellentesque.
+Risus ultricies tristique nulla aliquet enim tortor at. Fermentum odio eu feugiat pretium nibh ipsum.
+Volutpat sed cras ornare arcu dui. Scelerisque fermentum dui faucibus in ornare quam. Arcu cursus
+euismod quis< viverra nibh cras pulvinar mattis. Sed viverra tellus in hac habitasse platea. Quis
+commodo odio aenean sed. Cursus in hac habitasse platea dictumst quisque sagittis purus.
+
+Neque convallis >a cras semper auctor. Sit amet mauris commodo quis imperdiet massa. Ac ut consequat
+semper viverra nam libero justo laoreet sit. 'Adipiscing' commodo elit at imperdiet dui accumsan.
+Enim lobortis scelerisque fermentum dui faucibus in ornare. Natoque penatibus et magnis dis parturient
+montes nascetur ridiculus mus. At lectus urna duis convallis convallis tellus id interdum. Libero
+volutpat sed cras ornare arcu dui vivamus arcu. Cursus in hac habitasse platea dictumst quisque sagittis
+purus. Consequat id porta nibh venenatis cras sed felis.";
+
+        b.iter(|| {
+            criterion::black_box(escape(lorem_ipsum_with_escape_chars));
+        })
+    });
+    group.finish();
+}
+
+/// Benchmarks unescaping text encoded using XML rules
+fn unescaping(c: &mut Criterion) {
+    let mut group = c.benchmark_group("unescape_text");
+
+    group.bench_function("no_chars_to_unescape_long", |b| {
+        b.iter(|| {
+            criterion::black_box(unescape(LOREM_IPSUM_TEXT)).unwrap();
+        })
+    });
+
+    group.bench_function("no_chars_to_unescape_short", |b| {
+        b.iter(|| {
+            criterion::black_box(unescape(b"just a bit of text")).unwrap();
+        })
+    });
+
+    group.bench_function("char_reference", |b| {
+        b.iter(|| {
+            let text = b"prefix &#34;some stuff&#34;,&#x22;more stuff&#x22;";
+            criterion::black_box(unescape(text)).unwrap();
+            let text = b"&#38;&#60;";
+            criterion::black_box(unescape(text)).unwrap();
+        })
+    });
+
+    group.bench_function("entity_reference", |b| {
+        b.iter(|| {
+            let text = b"age &gt; 72 &amp;&amp; age &lt; 21";
+            criterion::black_box(unescape(text)).unwrap();
+            let text = b"&quot;what&apos;s that?&quot;";
+            criterion::black_box(unescape(text)).unwrap();
+        })
+    });
+
+    group.bench_function("mixed", |b| {
+        let text =
+b"Lorem ipsum dolor sit amet, &amp;consectetur adipiscing elit, sed do eiusmod tempor incididunt
+ut labore et dolore magna aliqua. Hac habitasse platea dictumst vestibulum rhoncus est pellentesque.
+Risus ultricies &quot;tristique nulla aliquet enim tortor&quot; at. Fermentum odio eu feugiat pretium
+nibh ipsum. Volutpat sed cras ornare arcu dui. Scelerisque fermentum dui faucibus in ornare quam. Arcu
+cursus euismod quis &#60;viverra nibh cras pulvinar mattis. Sed viverra tellus in hac habitasse platea.
+Quis commodo odio aenean sed. Cursus in hac habitasse platea dictumst quisque sagittis purus.
+
+Neque convallis a cras semper auctor. Sit amet mauris commodo quis imperdiet massa. Ac ut consequat
+semper viverra nam libero justo &#35; laoreet sit. Adipiscing commodo elit at imperdiet dui accumsan.
+Enim lobortis scelerisque fermentum dui faucibus in ornare. Natoque penatibus et magnis dis parturient
+montes nascetur ridiculus mus. At lectus urna &#33;duis convallis convallis tellus id interdum. Libero
+volutpat sed cras ornare arcu dui vivamus arcu. Cursus in hac habitasse platea dictumst quisque sagittis
+purus. Consequat id porta nibh venenatis cras sed felis.";
+
+        b.iter(|| {
+            criterion::black_box(unescape(text)).unwrap();
+        })
+    });
+    group.finish();
+}
+
+criterion_group!(
+    benches,
+    read_event,
+    bytes_text_unescaped,
+    read_namespaced_event,
+    one_event,
+    attributes,
+    escaping,
+    unescaping,
+);
diff --git a/compare/benches/bench.rs b/compare/benches/bench.rs
index fbb98a7..4a39863 100644
--- a/compare/benches/bench.rs
+++ b/compare/benches/bench.rs
@@ -5,7 +5,7 @@ use serde::Deserialize;
 use serde_xml_rs;
 use xml::reader::{EventReader, XmlEvent};
 
-static SOURCE: &str = include_str!("../../tests/sample_rss.xml");
+static SOURCE: &str = include_str!("../../tests/documents/sample_rss.xml");
 
 /// Runs benchmarks for several XML libraries using low-level API
 fn low_level_comparison(c: &mut Criterion) {
@@ -25,7 +25,7 @@ fn low_level_comparison(c: &mut Criterion) {
                 }
                 buf.clear();
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
 
@@ -49,7 +49,7 @@ fn low_level_comparison(c: &mut Criterion) {
                 }
                 input = &input[consumed..];
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
 
@@ -68,7 +68,7 @@ fn low_level_comparison(c: &mut Criterion) {
                     _ => (),
                 }
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
 
@@ -83,7 +83,7 @@ fn low_level_comparison(c: &mut Criterion) {
                     _ => (),
                 }
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
 
@@ -101,7 +101,7 @@ fn low_level_comparison(c: &mut Criterion) {
                     _ => (),
                 }
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
 
@@ -152,7 +152,7 @@ fn low_level_comparison(c: &mut Criterion) {
 
             assert_eq!(
                 tok.sink.0, 1550,
-                "Overall tag count in ./tests/sample_rss.xml"
+                "Overall tag count in ./tests/documents/sample_rss.xml"
             );
         })
     });
@@ -166,7 +166,7 @@ fn low_level_comparison(c: &mut Criterion) {
                     count += 1;
                 }
             }
-            assert_eq!(count, 1550, "Overall tag count in ./tests/sample_rss.xml");
+            assert_eq!(count, 1550, "Overall tag count in ./tests/documents/sample_rss.xml");
         })
     });
     group.finish();


Test patch:
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..316ee2d
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,48 @@
+# Document descrptions
+
+document.xml
+    medium length, mostly empty tags, a few short attributes per element, no escaping
+html5.html
+html5.txt
+libreoffice_document.fodt
+    long, mix of attributes and text, not much escaping, lots of non-ascii characters, lots of namespaces
+linescore.xml
+    medium length, lots of attributes, short attributes, few escapes
+opennews_all.rss
+players.xml
+    long, lots of attributes, short attributes, no text, no escapes
+rpm_filelists.xml
+    long, mostly medium-length text elements, not much escaping
+rpm_other.xml
+    long, mix of attributes and text, lots of escaping (both entity and char literal), long attributes
+rpm_primary.xml
+    long, mix of attributes and text, not much escaping, mix of attribute lengths, some namespaces
+rpm_primary2.xml
+    long, mix of attributes and text, not much escaping, mix of attribute lengths, some namespaces
+sample_1.xml
+    short, mix of attributes and text, lots of escapes
+sample_1_short.txt
+sample_1_full.txt
+sample_2.xml
+sample_2_short.txt
+sample_3.xml
+sample_2_full.txt
+sample_3_short.txt
+sample_3_full.txt
+sample_4.xml
+sample_4_short.txt
+sample_4_full.txt
+sample_5_short.txt
+sample_5_utf16bom.xml
+sample_5_full.txt
+sample_ns_short.txt
+sample_ns.xml
+    short, lots of namespaces, no escapes
+sample_rss.xml
+    long, few attributes, mix of attribute lengths, escapes in text content
+test_writer_indent_cdata.xml
+test_writer_indent.xml
+    medium length, lots of namespaces, no escaping
+test_writer.xml
+utf16be.xml
+utf16le.xml
diff --git a/tests/documents/libreoffice_document.fodt b/tests/documents/libreoffice_document.fodt
new file mode 100644
index 0000000..e0b78cf
--- /dev/null
+++ b/tests/documents/libreoffice_document.fodt
@@ -0,0 +1,481 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2022-06-28T20:26:31.048176115</meta:creation-date><dc:date>2022-06-28T20:27:13.444218412</dc:date><meta:editing-duration>PT43S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="4" meta:paragraph-count="154" meta:word-count="1319" meta:character-count="6916" meta:non-whitespace-character-count="5186"/><meta:generator>LibreOffice/7.2.7.2$Linux_X86_64 LibreOffice_project/20$Build-2</meta:generator></office:meta>
+ <office:settings>
+  <config:config-item-set config:name="ooo:view-settings">
+   <config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
+   <config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
+   <config:config-item config:name="ViewAreaWidth" config:type="long">49214</config:config-item>
+   <config:config-item config:name="ViewAreaHeight" config:type="long">22915</config:config-item>
+   <config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
+   <config:config-item-map-indexed config:name="Views">
+    <config:config-item-map-entry>
+     <config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
+     <config:config-item config:name="ViewLeft" config:type="long">15812</config:config-item>
+     <config:config-item config:name="ViewTop" config:type="long">2501</config:config-item>
+     <config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
+     <config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
+     <config:config-item config:name="VisibleRight" config:type="long">49213</config:config-item>
+     <config:config-item config:name="VisibleBottom" config:type="long">22913</config:config-item>
+     <config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
+     <config:config-item config:name="ViewLayoutColumns" config:type="short">1</config:config-item>
+     <config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
+     <config:config-item config:name="ZoomFactor" config:type="short">100</config:config-item>
+     <config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
+     <config:config-item config:name="KeepRatio" config:type="boolean">false</config:config-item>
+     <config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">false</config:config-item>
+    </config:config-item-map-entry>
+   </config:config-item-map-indexed>
+  </config:config-item-set>
+  <config:config-item-set config:name="ooo:configuration-settings">
+   <config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
+   <config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="GutterAtTop" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
+   <config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
+   <config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
+   <config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
+   <config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrintFaxName" config:type="string"/>
+   <config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
+   <config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
+   <config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="Rsid" config:type="int">426418</config:config-item>
+   <config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
+   <config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
+   <config:config-item config:name="PrinterName" config:type="string"/>
+   <config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="TabOverSpacing" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
+   <config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="RsidRoot" config:type="int">340756</config:config-item>
+   <config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="MathBaselineAlignment" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="SmallCapsPercentage66" config:type="boolean">false</config:config-item>
+   <config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
+   <config:config-item config:name="TabOverflow" config:type="boolean">true</config:config-item>
+  </config:config-item-set>
+ </office:settings>
+ <office:scripts>
+  <office:script script:language="ooo:Basic">
+   <ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink"/>
+  </office:script>
+ </office:scripts>
+ <office:font-face-decls>
+  <style:font-face style:name="Droid Sans Devanagari" svg:font-family="&apos;Droid Sans Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Droid Sans Devanagari1" svg:font-family="&apos;Droid Sans Devanagari&apos;" style:font-family-generic="swiss"/>
+  <style:font-face style:name="Liberation Mono" svg:font-family="&apos;Liberation Mono&apos;" style:font-family-generic="modern" style:font-pitch="fixed"/>
+  <style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/>
+  <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Sans CJK SC" svg:font-family="&apos;Noto Sans CJK SC&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Sans Mono CJK SC" svg:font-family="&apos;Noto Sans Mono CJK SC&apos;" style:font-family-generic="modern" style:font-pitch="fixed"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="graphic">
+   <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
+   <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
+    <style:tab-stops/>
+   </style:paragraph-properties>
+   <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Sans CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Droid Sans Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+  </style:default-style>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Noto Sans CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Droid Sans Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/>
+  </style:default-style>
+  <style:default-style style:family="table">
+   <style:table-properties table:border-model="collapsing"/>
+  </style:default-style>
+  <style:default-style style:family="table-row">
+   <style:table-row-properties fo:keep-together="auto"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+  <style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
+   <style:paragraph-properties fo:margin-top="0.1665in" fo:margin-bottom="0.0835in" style:contextual-spacing="false" fo:keep-with-next="always"/>
+   <style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable" fo:font-size="14pt" style:font-name-asian="Noto Sans CJK SC" style:font-family-asian="&apos;Noto Sans CJK SC&apos;" style:font-family-generic-asian="system" style:font-pitch-asian="variable" style:font-size-asian="14pt" style:font-name-complex="Droid Sans Devanagari" style:font-family-complex="&apos;Droid Sans Devanagari&apos;" style:font-family-generic-complex="system" style:font-pitch-complex="variable" style:font-size-complex="14pt"/>
+  </style:style>
+  <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
+   <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.0972in" style:contextual-spacing="false" fo:line-height="115%"/>
+  </style:style>
+  <style:style style:name="List" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="list">
+   <style:text-properties style:font-size-asian="12pt" style:font-name-complex="Droid Sans Devanagari1" style:font-family-complex="&apos;Droid Sans Devanagari&apos;" style:font-family-generic-complex="swiss"/>
+  </style:style>
+  <style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
+   <style:paragraph-properties fo:margin-top="0.0835in" fo:margin-bottom="0.0835in" style:contextual-spacing="false" text:number-lines="false" text:line-number="0"/>
+   <style:text-properties fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-name-complex="Droid Sans Devanagari1" style:font-family-complex="&apos;Droid Sans Devanagari&apos;" style:font-family-generic-complex="swiss" style:font-size-complex="12pt" style:font-style-complex="italic"/>
+  </style:style>
+  <style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index">
+   <style:paragraph-properties text:number-lines="false" text:line-number="0"/>
+   <style:text-properties fo:language="zxx" fo:country="none" style:font-size-asian="12pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Droid Sans Devanagari1" style:font-family-complex="&apos;Droid Sans Devanagari&apos;" style:font-family-generic-complex="swiss" style:language-complex="zxx" style:country-complex="none"/>
+  </style:style>
+  <style:style style:name="Preformatted_20_Text" style:display-name="Preformatted Text" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
+   <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0in" style:contextual-spacing="false"/>
+   <style:text-properties style:font-name="Liberation Mono" fo:font-family="&apos;Liberation Mono&apos;" style:font-family-generic="modern" style:font-pitch="fixed" fo:font-size="10pt" style:font-name-asian="Noto Sans Mono CJK SC" style:font-family-asian="&apos;Noto Sans Mono CJK SC&apos;" style:font-family-generic-asian="modern" style:font-pitch-asian="fixed" style:font-size-asian="10pt" style:font-name-complex="Liberation Mono" style:font-family-complex="&apos;Liberation Mono&apos;" style:font-family-generic-complex="modern" style:font-pitch-complex="fixed" style:font-size-complex="10pt"/>
+  </style:style>
+  <text:outline-style style:name="Outline">
+   <text:outline-level-style text:level="1" loext:num-list-format="%1%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="2" loext:num-list-format="%2%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="3" loext:num-list-format="%3%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="4" loext:num-list-format="%4%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="5" loext:num-list-format="%5%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="6" loext:num-list-format="%6%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="7" loext:num-list-format="%7%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="8" loext:num-list-format="%8%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="9" loext:num-list-format="%9%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="10" loext:num-list-format="%10%" style:num-format="">
+    <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+  </text:outline-style>
+  <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+  <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+  <text:linenumbering-configuration text:number-lines="false" text:offset="0.1965in" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Preformatted_20_Text">
+   <style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.1965in" style:contextual-spacing="false"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="8.5in" fo:page-height="11in" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.7874in" fo:margin-bottom="0.7874in" fo:margin-left="0.7874in" fo:margin-right="0.7874in" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.278in" style:layout-grid-ruby-height="0.139in" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0in" loext:margin-gutter="0in">
+    <style:footnote-sep style:width="0.0071in" style:distance-before-sep="0.0398in" style:distance-after-sep="0.0398in" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+   </style:page-layout-properties>
+   <style:header-style/>
+   <style:footer-style/>
+  </style:page-layout>
+  <style:style style:name="dp1" style:family="drawing-page">
+   <style:drawing-page-properties draw:background-size="full"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text text:use-soft-page-breaks="true">
+   <text:sequence-decls>
+    <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+   </text:sequence-decls>
+   <text:p text:style-name="Text_20_body">Original by Markus Kuhn, adapted for HTML by Martin Dürst.</text:p>
+   <text:p text:style-name="Preformatted_20_Text">UTF-8 encoded sample plain-text file</text:p>
+   <text:p text:style-name="Preformatted_20_Text">‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Markus Kuhn [ˈmaʳkʊs kuːn] &lt;mkuhn@acm.org&gt; — 1999-08-20</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">The ASCII compatible UTF-8 encoding of ISO 10646 and Unicode</text:p>
+   <text:p text:style-name="Preformatted_20_Text">plain-text files is defined in RFC 2279 and in ISO 10646-1 Annex R.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Using Unicode/UTF-8, you can write in emails and source code things such as</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Mathematics and Sciences:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>∮ E⋅da = Q, <text:s/>n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β),</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ &lt; a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B),</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Linguistics and dictionaries:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ]</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">APL:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>((V⍳V)=⍳⍴V)/V←,V <text:s text:c="3"/>⌷←⍳→⍴∆∇⊃‾⍎⍕⌈</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Nicer typography in plain text files:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>╔══════════════════════════════════════════╗</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• ‘single’ and “double” quotes <text:s text:c="8"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• Curly apostrophes: “We’ve been here” ║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• Latin-1 apostrophe and accents: &apos;´` <text:s/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• ‚deutsche‘ „Anführungszeichen“ <text:s text:c="6"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• †, ‡, ‰, •, 3–4, —, −5/+5, ™, … <text:s text:c="5"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="41"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• ASCII safety test: 1lI|, 0OD, 8B <text:s text:c="4"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="21"/>╭─────────╮ <text:s text:c="8"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="2"/>• the euro symbol: │ 14.95 € │ <text:s text:c="8"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║ <text:s text:c="21"/>╰─────────╯ <text:s text:c="8"/>║</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>╚══════════════════════════════════════════╝</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Greek (in Polytonic):</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>The Greek anthem:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Σὲ γνωρίζω ἀπὸ τὴν κόψη</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τοῦ σπαθιοῦ τὴν τρομερή,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>σὲ γνωρίζω ἀπὸ τὴν ὄψη</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ποὺ μὲ βία μετράει τὴ γῆ.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:soft-page-break/></text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>᾿Απ᾿ τὰ κόκκαλα βγαλμένη</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τῶν ῾Ελλήνων τὰ ἱερά</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>καὶ σὰν πρῶτα ἀνδρειωμένη</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά!</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>From a speech of Demosthenes in the 4th century BC:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ </text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>εἰς τοῦτο προήκοντα, <text:s/>ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Δημοσθένους, Γ´ ᾿Ολυνθιακὸς</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Georgian:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>From a Unicode conference invitation:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში,</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Russian:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>From a Unicode conference invitation:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Зарегистрируйтесь сейчас на Десятую Международную Конференцию по</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Конференция соберет широкий круг экспертов по <text:s/>вопросам глобального</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Интернета и Unicode, локализации и интернационализации, воплощению и</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>применению Unicode в различных операционных системах и программных</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>приложениях, шрифтах, верстке и многоязычных компьютерных системах.</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Thai (UCS Level 2):</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>classic &apos;San Gua&apos;):</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>[----------------------------|------------------------]</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="4"/>๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช <text:s/>พระปกเกศกองบู๊กู้ขึ้นใหม่</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>สิบสองกษัตริย์ก่อนหน้าแลถัดไป <text:s text:c="6"/>สององค์ไซร้โง่เขลาเบาปัญญา</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="4"/>ทรงนับถือขันทีเป็นที่พึ่ง <text:s text:c="10"/>บ้านเมืองจึงวิปริตเป็นนักหนา</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:soft-page-break/><text:s text:c="2"/>โฮจิ๋นเรียกทัพทั่วหัวเมืองมา <text:s text:c="8"/>หมายจะฆ่ามดชั่วตัวสำคัญ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="4"/>เหมือนขับไสไล่เสือจากเคหา <text:s text:c="5"/>รับหมาป่าเข้ามาเลยอาสัญ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ฝ่ายอ้องอุ้นยุแยกให้แตกกัน <text:s text:c="9"/>ใช้สาวนั้นเป็นชนวนชื่นชวนใจ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="4"/>พลันลิฉุยกุยกีกลับก่อเหตุ <text:s text:c="9"/>ช่างอาเพศจริงหนาฟ้าร้องไห้</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ต้องรบราฆ่าฟันจนบรรลัย <text:s text:c="10"/>ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>(The above is a two-column text. If combining characters are handled</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>correctly, the lines of the second column should be aligned with the</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>| character above.)</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Ethiopian:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Proverbs in the Amharic language:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ሰማይ አይታረስ ንጉሥ አይከሰስ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ብላ ካለኝ እንደአባቴ በቆመጠኝ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ጌጥ ያለቤቱ ቁምጥና ነው።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>የአፍ ወለምታ በቅቤ አይታሽም።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>አይጥ በበላ ዳዋ ተመታ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ሲተረጉሙ ይደረግሙ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ድር ቢያብር አንበሳ ያስር።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ሥራ ከመፍታት ልጄን ላፋታት።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ተንጋሎ ቢተፉ ተመልሶ ባፉ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>እግርህን በፍራሽህ ልክ ዘርጋ።</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Runes:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>(Old English, which transcribed into Latin reads &apos;He cwaeth that he</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>bude thaem lande northweardum with tha Westsae.&apos; and means &apos;He said</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>that he lived in the northern land near the Western Sea.&apos;)</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Braille:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡌⠁⠧⠑ ⠼⠁⠒ <text:s/>⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ </text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ </text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ </text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:soft-page-break/><text:s text:c="2"/>⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>(The first couple of paragraphs of &quot;A Christmas Carol&quot; by Dickens)</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Compact font selection example text:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ ﬁ�⑀₂ἠḂӥẄɐː⍎אԱა</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Greetings in various languages:</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>Hello world, Καλημέρα κόσμε, コンニチハ</text:p>
+   <text:p text:style-name="Preformatted_20_Text"/>
+   <text:p text:style-name="Preformatted_20_Text">Box drawing alignment tests: <text:s text:c="41"/>█</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="70"/>▉</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>╔══╦══╗ <text:s/>┌──┬──┐ <text:s/>╭──┬──╮ <text:s/>╭──┬──╮ <text:s/>┏━━┳━━┓ <text:s/>┎┒┏┑ <text:s text:c="2"/>╷ <text:s/>╻ ┏┯┓ ┌┰┐ <text:s text:c="3"/>▊ ╱╲╱╲╳╳╳</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║┌─╨─┐║ <text:s/>│╔═╧═╗│ <text:s/>│╒═╪═╕│ <text:s/>│╓─╁─╖│ <text:s/>┃┌─╂─┐┃ <text:s/>┗╃╄┙ <text:s/>╶┼╴╺╋╸┠┼┨ ┝╋┥ <text:s text:c="3"/>▋ ╲╱╲╱╳╳╳</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║│╲ ╱│║ <text:s/>│║ <text:s text:c="2"/>║│ <text:s/>││ │ ││ <text:s/>│║ ┃ ║│ <text:s/>┃│ ╿ │┃ <text:s/>┍╅╆┓ <text:s text:c="2"/>╵ <text:s/>╹ ┗┷┛ └┸┘ <text:s text:c="3"/>▌ ╱╲╱╲╳╳╳</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>╠╡ ╳ ╞╣ <text:s/>├╢ <text:s text:c="2"/>╟┤ <text:s/>├┼─┼─┼┤ <text:s/>├╫─╂─╫┤ <text:s/>┣┿╾┼╼┿┫ <text:s/>┕┛┖┚ <text:s text:c="4"/>┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║│╱ ╲│║ <text:s/>│║ <text:s text:c="2"/>║│ <text:s/>││ │ ││ <text:s/>│║ ┃ ║│ <text:s/>┃│ ╽ │┃ <text:s/>░░▒▒▓▓██ ┊ <text:s/>┆ ╎ ╏ <text:s/>┇ ┋ ▎</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>║└─╥─┘║ <text:s/>│╚═╤═╝│ <text:s/>│╘═╪═╛│ <text:s/>│╙─╀─╜│ <text:s/>┃└─╂─┘┃ <text:s/>░░▒▒▓▓██ ┊ <text:s/>┆ ╎ ╏ <text:s/>┇ ┋ ▏</text:p>
+   <text:p text:style-name="Preformatted_20_Text"><text:s text:c="2"/>╚══╩══╝ <text:s/>└──┴──┘ <text:s/>╰──┴──╯ <text:s/>╰──┴──╯ <text:s/>┗━━┻━━┛ <text:s text:c="10"/>└╌╌┘ ╎ ┗╍╍┛ ┋ <text:s/>▁▂▃▄▅▆▇█</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="Standard"/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/tests/linescore.xml b/tests/documents/linescore.xml
similarity index 100%
rename from tests/linescore.xml
rename to tests/documents/linescore.xml
diff --git a/tests/players.xml b/tests/documents/players.xml
similarity index 100%
rename from tests/players.xml
rename to tests/documents/players.xml
diff --git a/tests/documents/rpm_filelists.xml b/tests/documents/rpm_filelists.xml
new file mode 100644
index 0000000..7b3a7ae
--- /dev/null
+++ b/tests/documents/rpm_filelists.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<filelists xmlns="http://linux.duke.edu/metadata/filelists" packages="12">
+    <package pkgid="328abd9aab5206b5ea74fdbcec38d146851a2fe831b3e5dcebdb23c31c4bdb15" name="apr-util-devel" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/share/aclocal/find_apu.m4</file>
+        <file>/usr/lib64/pkgconfig/apr-util-1.pc</file>
+        <file>/usr/lib64/libaprutil-1.so</file>
+        <file>/usr/lib64/libaprutil-1.la</file>
+        <file>/usr/include/apr-1/apu_want.h</file>
+        <file>/usr/include/apr-1/apu_version.h</file>
+        <file>/usr/include/apr-1/apu_errno.h</file>
+        <file>/usr/include/apr-1/apu.h</file>
+        <file>/usr/include/apr-1/apr_xml.h</file>
+        <file>/usr/include/apr-1/apr_xlate.h</file>
+        <file>/usr/include/apr-1/apr_uuid.h</file>
+        <file>/usr/include/apr-1/apr_uri.h</file>
+        <file>/usr/include/apr-1/apr_thread_pool.h</file>
+        <file>/usr/include/apr-1/apr_strmatch.h</file>
+        <file>/usr/include/apr-1/apr_siphash.h</file>
+        <file>/usr/include/apr-1/apr_sha1.h</file>
+        <file>/usr/include/apr-1/apr_sdbm.h</file>
+        <file>/usr/include/apr-1/apr_rmm.h</file>
+        <file>/usr/include/apr-1/apr_reslist.h</file>
+        <file>/usr/include/apr-1/apr_redis.h</file>
+        <file>/usr/include/apr-1/apr_queue.h</file>
+        <file>/usr/include/apr-1/apr_optional_hooks.h</file>
+        <file>/usr/include/apr-1/apr_optional.h</file>
+        <file>/usr/include/apr-1/apr_memcache.h</file>
+        <file>/usr/include/apr-1/apr_md5.h</file>
+        <file>/usr/include/apr-1/apr_md4.h</file>
+        <file>/usr/include/apr-1/apr_ldap_url.h</file>
+        <file>/usr/include/apr-1/apr_ldap_rebind.h</file>
+        <file>/usr/include/apr-1/apr_ldap_option.h</file>
+        <file>/usr/include/apr-1/apr_ldap_init.h</file>
+        <file>/usr/include/apr-1/apr_ldap.h</file>
+        <file>/usr/include/apr-1/apr_hooks.h</file>
+        <file>/usr/include/apr-1/apr_dbm.h</file>
+        <file>/usr/include/apr-1/apr_dbd.h</file>
+        <file>/usr/include/apr-1/apr_date.h</file>
+        <file>/usr/include/apr-1/apr_crypto.h</file>
+        <file>/usr/include/apr-1/apr_buckets.h</file>
+        <file>/usr/include/apr-1/apr_base64.h</file>
+        <file>/usr/include/apr-1/apr_anylock.h</file>
+        <file>/usr/bin/apu-1-config</file>
+    </package>
+    <package pkgid="bba430bebeec583e817372badbc957259d210e3081f5913a831594eb48f48f64" name="apr-util-bdb" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_dbm_db.so</file>
+        <file>/usr/lib64/apr-util-1/apr_dbm_db-1.so</file>
+        <file>/usr/lib/.build-id/1c/aa4768d439e50d084a67ec81fbcd3df9c058fc</file>
+        <file type="dir">/usr/lib/.build-id/1c</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="403ef93e442ecdb6ea4846e620ffec3c40f7d5bc9d43a4a9055a9540b98f180a" name="apr-util-pgsql" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_dbd_pgsql.so</file>
+        <file>/usr/lib64/apr-util-1/apr_dbd_pgsql-1.so</file>
+        <file>/usr/lib/.build-id/31/ce21d792563c765e73a8aba098540365708ac6</file>
+        <file type="dir">/usr/lib/.build-id/31</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="7bdd897b6a875ea0ea2d0269338be903b69c5f394bb9a682800ccd8f466ab186" name="apr-util-openssl" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_crypto_openssl.so</file>
+        <file>/usr/lib64/apr-util-1/apr_crypto_openssl-1.so</file>
+        <file>/usr/lib/.build-id/e1/aaeed41b3467d28383f986e36cb17fca822321</file>
+        <file type="dir">/usr/lib/.build-id/e1</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="2e7e855181b7e3053fbe067aa6d34e75b73e403215390852666de7be254ca607" name="libacl" arch="x86_64">
+        <version epoch="0" ver="2.2.53" rel="1.el8"/>
+        <file>/usr/lib64/libacl.so.1.1.2253</file>
+        <file>/usr/lib64/libacl.so.1</file>
+        <file>/usr/lib/.build-id/e3/4e4bf1c9f6060fdf5d1da6f04247ee6d3e56de</file>
+        <file type="dir">/usr/lib/.build-id/e3</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="4d5eae10d5108a02e293a033b622544a18d200733ad9f0727973d579b20c1fb3" name="libacl-devel" arch="x86_64">
+        <version epoch="0" ver="2.2.53" rel="1.el8"/>
+        <file>/usr/share/man/man3/acl_valid.3.gz</file>
+        <file>/usr/share/man/man3/acl_to_text.3.gz</file>
+        <file>/usr/share/man/man3/acl_to_any_text.3.gz</file>
+        <file>/usr/share/man/man3/acl_size.3.gz</file>
+        <file>/usr/share/man/man3/acl_set_tag_type.3.gz</file>
+        <file>/usr/share/man/man3/acl_set_qualifier.3.gz</file>
+        <file>/usr/share/man/man3/acl_set_permset.3.gz</file>
+        <file>/usr/share/man/man3/acl_set_file.3.gz</file>
+        <file>/usr/share/man/man3/acl_set_fd.3.gz</file>
+        <file>/usr/share/man/man3/acl_init.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_tag_type.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_qualifier.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_permset.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_perm.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_file.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_fd.3.gz</file>
+        <file>/usr/share/man/man3/acl_get_entry.3.gz</file>
+        <file>/usr/share/man/man3/acl_from_text.3.gz</file>
+        <file>/usr/share/man/man3/acl_from_mode.3.gz</file>
+        <file>/usr/share/man/man3/acl_free.3.gz</file>
+        <file>/usr/share/man/man3/acl_extended_file_nofollow.3.gz</file>
+        <file>/usr/share/man/man3/acl_extended_file.3.gz</file>
+        <file>/usr/share/man/man3/acl_extended_fd.3.gz</file>
+        <file>/usr/share/man/man3/acl_error.3.gz</file>
+        <file>/usr/share/man/man3/acl_equiv_mode.3.gz</file>
+        <file>/usr/share/man/man3/acl_entries.3.gz</file>
+        <file>/usr/share/man/man3/acl_dup.3.gz</file>
+        <file>/usr/share/man/man3/acl_delete_perm.3.gz</file>
+        <file>/usr/share/man/man3/acl_delete_entry.3.gz</file>
+        <file>/usr/share/man/man3/acl_delete_def_file.3.gz</file>
+        <file>/usr/share/man/man3/acl_create_entry.3.gz</file>
+        <file>/usr/share/man/man3/acl_copy_int.3.gz</file>
+        <file>/usr/share/man/man3/acl_copy_ext.3.gz</file>
+        <file>/usr/share/man/man3/acl_copy_entry.3.gz</file>
+        <file>/usr/share/man/man3/acl_cmp.3.gz</file>
+        <file>/usr/share/man/man3/acl_clear_perms.3.gz</file>
+        <file>/usr/share/man/man3/acl_check.3.gz</file>
+        <file>/usr/share/man/man3/acl_calc_mask.3.gz</file>
+        <file>/usr/share/man/man3/acl_add_perm.3.gz</file>
+        <file>/usr/lib64/pkgconfig/libacl.pc</file>
+        <file>/usr/lib64/libacl.so</file>
+        <file>/usr/include/sys/acl.h</file>
+        <file>/usr/include/acl/libacl.h</file>
+        <file type="dir">/usr/include/acl</file>
+    </package>
+    <package pkgid="51e80e35ebaa69f7e72c1d9788e569107aee3b4414347324a8983911a2af46d6" name="acl" arch="x86_64">
+        <version epoch="0" ver="2.2.53" rel="1.el8"/>
+        <file>/usr/share/man/man5/acl.5.gz</file>
+        <file>/usr/share/man/man1/setfacl.1.gz</file>
+        <file>/usr/share/man/man1/getfacl.1.gz</file>
+        <file>/usr/share/man/man1/chacl.1.gz</file>
+        <file>/usr/share/locale/sv/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/pl/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/gl/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/fr/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/es/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/en@quot/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/en@boldquot/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/locale/de/LC_MESSAGES/acl.mo</file>
+        <file>/usr/share/licenses/acl/COPYING.LGPL</file>
+        <file>/usr/share/licenses/acl/COPYING</file>
+        <file type="dir">/usr/share/licenses/acl</file>
+        <file>/usr/lib/.build-id/ea/bd0b51e30f5b8f7a60e8a713ea3e8e87da158a</file>
+        <file type="dir">/usr/lib/.build-id/ea</file>
+        <file>/usr/lib/.build-id/8c/f58e99260c995bf9a178a1eec3f0b6718420cb</file>
+        <file type="dir">/usr/lib/.build-id/8c</file>
+        <file>/usr/lib/.build-id/68/0459a093ce0f41f4da38f101a65134b6239d7d</file>
+        <file type="dir">/usr/lib/.build-id/68</file>
+        <file type="dir">/usr/lib/.build-id</file>
+        <file>/usr/bin/setfacl</file>
+        <file>/usr/bin/getfacl</file>
+        <file>/usr/bin/chacl</file>
+    </package>
+    <package pkgid="56fbbf08e857582e22bb95d252a3e1735e4476ac64cdd4d7e607974876ccbb61" name="apr-util" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/share/doc/apr-util/NOTICE</file>
+        <file>/usr/share/doc/apr-util/LICENSE</file>
+        <file>/usr/share/doc/apr-util/CHANGES</file>
+        <file type="dir">/usr/share/doc/apr-util</file>
+        <file>/usr/lib64/libaprutil-1.so.0.6.1</file>
+        <file>/usr/lib64/libaprutil-1.so.0</file>
+        <file type="dir">/usr/lib64/apr-util-1</file>
+        <file>/usr/lib/.build-id/9a/1329e49ef7c955cbb975d72208c04f3a43df21</file>
+        <file type="dir">/usr/lib/.build-id/9a</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="901e85b18bba94983531accfe46d9649cb23e50222adf5dc15657576ab7d55e4" name="apr-util-ldap" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_ldap.so</file>
+        <file>/usr/lib64/apr-util-1/apr_ldap-1.so</file>
+        <file>/usr/lib/.build-id/de/6f295ab2082ad9db5dc6e4f89f15310f7476b5</file>
+        <file type="dir">/usr/lib/.build-id/de</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="6600d5b2801be6e85d5ed0f69b82b0f0ac9b2c9cf89b4d6a130d87f4bee575f6" name="apr-util-mysql" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_dbd_mysql.so</file>
+        <file>/usr/lib64/apr-util-1/apr_dbd_mysql-1.so</file>
+        <file>/usr/lib/.build-id/12/5b8186db5c0fd8df6f367914de98afde368164</file>
+        <file type="dir">/usr/lib/.build-id/12</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="b97be76fe95186f4c3ec3db709793fcab944eabf091614f46ee8b4271097b6ff" name="apr-util-sqlite" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_dbd_sqlite3.so</file>
+        <file>/usr/lib64/apr-util-1/apr_dbd_sqlite3-1.so</file>
+        <file>/usr/lib/.build-id/6a/11b542c4986631e17444858fc7f09a645c4e08</file>
+        <file type="dir">/usr/lib/.build-id/6a</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+    <package pkgid="72f87880ca38933b9158e3993ffff9f33267f3a0e32e9791c390190587f40cc5" name="apr-util-odbc" arch="x86_64">
+        <version epoch="0" ver="1.6.1" rel="6.el8"/>
+        <file>/usr/lib64/apr-util-1/apr_dbd_odbc.so</file>
+        <file>/usr/lib64/apr-util-1/apr_dbd_odbc-1.so</file>
+        <file>/usr/lib/.build-id/bb/857d0925e0fc4182a542db4338cc99abd269c4</file>
+        <file type="dir">/usr/lib/.build-id/bb</file>
+        <file type="dir">/usr/lib/.build-id</file>
+    </package>
+</filelists>
diff --git a/tests/documents/rpm_other.xml b/tests/documents/rpm_other.xml
new file mode 100644
index 0000000..fb2c867
--- /dev/null
+++ b/tests/documents/rpm_other.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<otherdata xmlns="http://linux.duke.edu/metadata/other" packages="12">
+<package pkgid="328abd9aab5206b5ea74fdbcec38d146851a2fe831b3e5dcebdb23c31c4bdb15" name="apr-util-devel" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="bba430bebeec583e817372badbc957259d210e3081f5913a831594eb48f48f64" name="apr-util-bdb" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="403ef93e442ecdb6ea4846e620ffec3c40f7d5bc9d43a4a9055a9540b98f180a" name="apr-util-pgsql" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="7bdd897b6a875ea0ea2d0269338be903b69c5f394bb9a682800ccd8f466ab186" name="apr-util-openssl" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="2e7e855181b7e3053fbe067aa6d34e75b73e403215390852666de7be254ca607" name="libacl" arch="x86_64">
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.53-1" date="1530532800">- new upstream release</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-21" date="1520942400">- update link to POSIX.1e draft in acl(5) man page (#1510527)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-20" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Igor Gnatenko &lt;ignatenkobrain@fedoraproject.org&gt; - 2.2.52-19" date="1517745600">- Switch to %ldconfig_scriptlets</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-18" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-17" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-16" date="1500897600">- fix test-suite failure with perl-5.26.0 (#1473845)
+- update URL of the upstream source tarball</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-15" date="1495108800">- setfacl.1: document the meaning of '-' in perms (#1337039)
+- avoid failure of %check when building as root (#1085389)
+- apply patches automatically to ease maintenance</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-14" date="1495022400">- drop obsolete BuildRoot and Group tags
+- fix spurious acl_check() failure on setfacl --restore (#1451826)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-13" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="4d5eae10d5108a02e293a033b622544a18d200733ad9f0727973d579b20c1fb3" name="libacl-devel" arch="x86_64">
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.53-1" date="1530532800">- new upstream release</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-21" date="1520942400">- update link to POSIX.1e draft in acl(5) man page (#1510527)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-20" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Igor Gnatenko &lt;ignatenkobrain@fedoraproject.org&gt; - 2.2.52-19" date="1517745600">- Switch to %ldconfig_scriptlets</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-18" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-17" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-16" date="1500897600">- fix test-suite failure with perl-5.26.0 (#1473845)
+- update URL of the upstream source tarball</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-15" date="1495108800">- setfacl.1: document the meaning of '-' in perms (#1337039)
+- avoid failure of %check when building as root (#1085389)
+- apply patches automatically to ease maintenance</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-14" date="1495022400">- drop obsolete BuildRoot and Group tags
+- fix spurious acl_check() failure on setfacl --restore (#1451826)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-13" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="51e80e35ebaa69f7e72c1d9788e569107aee3b4414347324a8983911a2af46d6" name="acl" arch="x86_64">
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.53-1" date="1530532800">- new upstream release</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-21" date="1520942400">- update link to POSIX.1e draft in acl(5) man page (#1510527)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-20" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Igor Gnatenko &lt;ignatenkobrain@fedoraproject.org&gt; - 2.2.52-19" date="1517745600">- Switch to %ldconfig_scriptlets</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-18" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-17" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-16" date="1500897600">- fix test-suite failure with perl-5.26.0 (#1473845)
+- update URL of the upstream source tarball</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-15" date="1495108800">- setfacl.1: document the meaning of '-' in perms (#1337039)
+- avoid failure of %check when building as root (#1085389)
+- apply patches automatically to ease maintenance</changelog>
+  <changelog author="Kamil Dudka &lt;kdudka@redhat.com&gt; 2.2.52-14" date="1495022400">- drop obsolete BuildRoot and Group tags
+- fix spurious acl_check() failure on setfacl --restore (#1451826)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 2.2.52-13" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="56fbbf08e857582e22bb95d252a3e1735e4476ac64cdd4d7e607974876ccbb61" name="apr-util" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="901e85b18bba94983531accfe46d9649cb23e50222adf5dc15657576ab7d55e4" name="apr-util-ldap" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="6600d5b2801be6e85d5ed0f69b82b0f0ac9b2c9cf89b4d6a130d87f4bee575f6" name="apr-util-mysql" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="b97be76fe95186f4c3ec3db709793fcab944eabf091614f46ee8b4271097b6ff" name="apr-util-sqlite" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+<package pkgid="72f87880ca38933b9158e3993ffff9f33267f3a0e32e9791c390190587f40cc5" name="apr-util-odbc" arch="x86_64">
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.1-6" date="1538395200">- Recommends: apr-util-openssl, apr-util-bdb (#1633973)</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.6.1-5" date="1518004800">- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild</changelog>
+  <changelog author="Florian Weimer &lt;fweimer@redhat.com&gt; - 1.6.1-4" date="1516968000">- Rebuild with new build flags embedded in apr</changelog>
+  <changelog author="Bj&#xF6;rn Esser &lt;besser82@fedoraproject.org&gt; - 1.6.1-3" date="1516449600">- Rebuilt for switch to libxcrypt</changelog>
+  <changelog author="Honza Horak &lt;hhorak@redhat.com&gt; - 1.6.1-2" date="1513684800">- Build with mariadb-connector-c</changelog>
+  <changelog author="Lubo&#x161; Uhliarik &lt;luhliari@redhat.com&gt; - 1.6.1-1" date="1508932800">- new version 1.6.1</changelog>
+  <changelog author="Joe Orton &lt;jorton@redhat.com&gt; - 1.6.0-1" date="1503316800">- update to 1.6.0 (#1460831)
+- move bdb support to loadable DSO in apr-util-dbd subpackage
+- drop NSS, freetds support</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-7" date="1501675200">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-6" date="1501070400">- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild</changelog>
+  <changelog author="Fedora Release Engineering &lt;releng@fedoraproject.org&gt; - 1.5.4-5" date="1486728000">- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild</changelog>
+</package>
+</otherdata>
diff --git a/tests/documents/rpm_primary.xml b/tests/documents/rpm_primary.xml
new file mode 100644
index 0000000..f3264ef
--- /dev/null
+++ b/tests/documents/rpm_primary.xml
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata xmlns="http://linux.duke.edu/metadata/common" xmlns:rpm="http://linux.duke.edu/metadata/rpm" packages="12">
+<package type="rpm">
+  <name>apr-util-devel</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">328abd9aab5206b5ea74fdbcec38d146851a2fe831b3e5dcebdb23c31c4bdb15</checksum>
+  <summary>APR utility library development kit</summary>
+  <description>This package provides the support files which can be used to
+build applications using the APR utility library.  The mission
+of the Apache Portable Runtime (APR) is to provide a free
+library of C data structures and routines.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323552" build="1632323489"/>
+  <size package="86776" installed="324933" archive="330880"/>
+  <location href="Packages/a/apr-util-devel-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="25020"/>
+    <rpm:provides>
+      <rpm:entry name="pkgconfig(apr-util-1)" flags="EQ" epoch="0" ver="1.6.1"/>
+      <rpm:entry name="libtool(/usr/lib64/libaprutil-1.la)"/>
+      <rpm:entry name="apr-util-devel(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-devel" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="pkgconfig(apr-1)"/>
+      <rpm:entry name="pkgconfig"/>
+      <rpm:entry name="openldap-devel(x86-64)"/>
+      <rpm:entry name="libdb-devel(x86-64)"/>
+      <rpm:entry name="libaprutil-1.so.0()(64bit)"/>
+      <rpm:entry name="expat-devel(x86-64)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-devel(x86-64)"/>
+      <rpm:entry name="/usr/bin/pkg-config"/>
+      <rpm:entry name="/bin/sh"/>
+    </rpm:requires>
+    <file>/usr/bin/apu-1-config</file>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-bdb</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">bba430bebeec583e817372badbc957259d210e3081f5913a831594eb48f48f64</checksum>
+  <summary>APR utility library Berkeley DB driver</summary>
+  <description>This package provides the Berkeley DB driver for the apr-util
+DBM (database abstraction) interface.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323556" build="1632323489"/>
+  <size package="24064" installed="11760" archive="12688"/>
+  <location href="Packages/a/apr-util-bdb-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19820"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-bdb(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-bdb" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.4)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libdb-5.3.so()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-pgsql</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">403ef93e442ecdb6ea4846e620ffec3c40f7d5bc9d43a4a9055a9540b98f180a</checksum>
+  <summary>APR utility library PostgreSQL DBD driver</summary>
+  <description>This package provides the PostgreSQL driver for the apr-util
+DBD (database abstraction) interface.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323560" build="1632323489"/>
+  <size package="29352" installed="24360" archive="25300"/>
+  <location href="Packages/a/apr-util-pgsql-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19876"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-pgsql(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-pgsql" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.14)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libpq.so.5(RHPG_9.6)(64bit)"/>
+      <rpm:entry name="libpq.so.5()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-openssl</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">7bdd897b6a875ea0ea2d0269338be903b69c5f394bb9a682800ccd8f466ab186</checksum>
+  <summary>APR utility library OpenSSL crypto support</summary>
+  <description>This package provides the OpenSSL crypto support for the apr-util.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323557" build="1632323489"/>
+  <size package="26336" installed="20288" archive="21248"/>
+  <location href="Packages/a/apr-util-openssl-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19996"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-openssl(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-openssl" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.14)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libssl.so.1.1()(64bit)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libcrypto.so.1.1(OPENSSL_1_1_0)(64bit)"/>
+      <rpm:entry name="libcrypto.so.1.1()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>libacl</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <checksum type="sha256" pkgid="YES">2e7e855181b7e3053fbe067aa6d34e75b73e403215390852666de7be254ca607</checksum>
+  <summary>Dynamic library for access control list support</summary>
+  <description>This package contains the libacl.so dynamic library which contains
+the POSIX 1003.1e draft standard 17 functions for manipulating access
+control lists.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>https://savannah.nongnu.org/projects/acl</url>
+  <time file="1632323348" build="1632323300"/>
+  <size package="34280" installed="37784" archive="38688"/>
+  <location href="Packages/l/libacl-2.2.53-1.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>LGPLv2+</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>System Environment/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>acl-2.2.53-1.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="18476"/>
+    <rpm:provides>
+      <rpm:entry name="libacl.so.1(ACL_1.2)(64bit)"/>
+      <rpm:entry name="libacl.so.1(ACL_1.1)(64bit)"/>
+      <rpm:entry name="libacl.so.1(ACL_1.0)(64bit)"/>
+      <rpm:entry name="libacl.so.1()(64bit)"/>
+      <rpm:entry name="libacl(x86-64)" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+      <rpm:entry name="libacl" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.14)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libattr.so.1()(64bit)"/>
+    </rpm:requires>
+    <rpm:conflicts>
+      <rpm:entry name="filesystem" flags="LT" epoch="0" ver="3"/>
+    </rpm:conflicts>
+  </format>
+</package>
+<package type="rpm">
+  <name>libacl-devel</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <checksum type="sha256" pkgid="YES">4d5eae10d5108a02e293a033b622544a18d200733ad9f0727973d579b20c1fb3</checksum>
+  <summary>Files needed for building programs with libacl</summary>
+  <description>This package contains header files and documentation needed to develop
+programs which make use of the access control list programming interface
+defined in POSIX 1003.1e draft standard 17.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>https://savannah.nongnu.org/projects/acl</url>
+  <time file="1632323346" build="1632323300"/>
+  <size package="79776" installed="60587" archive="67384"/>
+  <location href="Packages/l/libacl-devel-2.2.53-1.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>LGPLv2+</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>acl-2.2.53-1.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="23940"/>
+    <rpm:provides>
+      <rpm:entry name="pkgconfig(libacl)" flags="EQ" epoch="0" ver="2.2.53"/>
+      <rpm:entry name="libacl-devel(x86-64)" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+      <rpm:entry name="libacl-devel" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libattr-devel"/>
+      <rpm:entry name="libacl.so.1()(64bit)"/>
+      <rpm:entry name="libacl" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+      <rpm:entry name="/usr/bin/pkg-config"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>acl</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="2.2.53" rel="1.el8"/>
+  <checksum type="sha256" pkgid="YES">51e80e35ebaa69f7e72c1d9788e569107aee3b4414347324a8983911a2af46d6</checksum>
+  <summary>Access control list utilities</summary>
+  <description>This package contains the getfacl and setfacl utilities needed for
+manipulating access control lists.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>https://savannah.nongnu.org/projects/acl</url>
+  <time file="1632323342" build="1632323300"/>
+  <size package="81780" installed="198340" archive="202240"/>
+  <location href="Packages/a/acl-2.2.53-1.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>GPLv2+</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Unspecified</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>acl-2.2.53-1.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="21884"/>
+    <rpm:provides>
+      <rpm:entry name="acl(x86-64)" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+      <rpm:entry name="acl" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.14)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libattr.so.1()(64bit)"/>
+      <rpm:entry name="libacl.so.1(ACL_1.0)(64bit)"/>
+      <rpm:entry name="libacl.so.1()(64bit)"/>
+      <rpm:entry name="libacl" flags="EQ" epoch="0" ver="2.2.53" rel="1.el8"/>
+    </rpm:requires>
+    <file>/usr/bin/setfacl</file>
+    <file>/usr/bin/getfacl</file>
+    <file>/usr/bin/chacl</file>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">56fbbf08e857582e22bb95d252a3e1735e4476ac64cdd4d7e607974876ccbb61</checksum>
+  <summary>Apache Portable Runtime Utility library</summary>
+  <description>The mission of the Apache Portable Runtime (APR) is to provide a
+free library of C data structures and routines.  This library
+contains additional utility interfaces for APR; including support
+for XML, LDAP, database interfaces, URI parsing and more.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323552" build="1632323489"/>
+  <size package="106440" installed="221743" archive="223368"/>
+  <location href="Packages/a/apr-util-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>System Environment/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="21180"/>
+    <rpm:provides>
+      <rpm:entry name="libaprutil-1.so.0()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.25)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libuuid.so.1()(64bit)"/>
+      <rpm:entry name="libpthread.so.0(GLIBC_2.2.5)(64bit)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libexpat.so.1()(64bit)"/>
+      <rpm:entry name="libdl.so.2()(64bit)"/>
+      <rpm:entry name="libcrypt.so.1(XCRYPT_2.0)(64bit)"/>
+      <rpm:entry name="libcrypt.so.1()(64bit)"/>
+      <rpm:entry name="libapr-1.so.0()(64bit)"/>
+      <rpm:entry name="/sbin/ldconfig"/>
+      <rpm:entry name="/sbin/ldconfig" pre="1"/>
+    </rpm:requires>
+    <rpm:recommends>
+      <rpm:entry name="apr-util-openssl(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-bdb(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:recommends>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-ldap</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">901e85b18bba94983531accfe46d9649cb23e50222adf5dc15657576ab7d55e4</checksum>
+  <summary>APR utility library LDAP support</summary>
+  <description>This package provides the LDAP support for the apr-util.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323553" build="1632323489"/>
+  <size package="25000" installed="16448" archive="17372"/>
+  <location href="Packages/a/apr-util-ldap-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19808"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-ldap(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-ldap" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.4)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libldap_r-2.4.so.2()(64bit)"/>
+      <rpm:entry name="liblber-2.4.so.2()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-mysql</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">6600d5b2801be6e85d5ed0f69b82b0f0ac9b2c9cf89b4d6a130d87f4bee575f6</checksum>
+  <summary>APR utility library MySQL DBD driver</summary>
+  <description>This package provides the MySQL driver for the apr-util DBD
+(database abstraction) interface.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323559" build="1632323489"/>
+  <size package="29436" installed="28472" archive="29412"/>
+  <location href="Packages/a/apr-util-mysql-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19920"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-mysql(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-mysql" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.4)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libmariadb.so.3(libmysqlclient_18)(64bit)"/>
+      <rpm:entry name="libmariadb.so.3()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-sqlite</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">b97be76fe95186f4c3ec3db709793fcab944eabf091614f46ee8b4271097b6ff</checksum>
+  <summary>APR utility library SQLite DBD driver</summary>
+  <description>This package provides the SQLite driver for the apr-util DBD
+(database abstraction) interface.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323546" build="1632323489"/>
+  <size package="27192" installed="20232" archive="21180"/>
+  <location href="Packages/a/apr-util-sqlite-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19844"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-sqlite(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-sqlite" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.4)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libsqlite3.so.0()(64bit)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+<package type="rpm">
+  <name>apr-util-odbc</name>
+  <arch>x86_64</arch>
+  <version epoch="0" ver="1.6.1" rel="6.el8"/>
+  <checksum type="sha256" pkgid="YES">72f87880ca38933b9158e3993ffff9f33267f3a0e32e9791c390190587f40cc5</checksum>
+  <summary>APR utility library ODBC DBD driver</summary>
+  <description>This package provides the ODBC driver for the apr-util DBD
+(database abstraction) interface.</description>
+  <packager>AlmaLinux Packaging Team &lt;packager@almalinux.org&gt;</packager>
+  <url>http://apr.apache.org/</url>
+  <time file="1632323545" build="1632323489"/>
+  <size package="33120" installed="32704" archive="33644"/>
+  <location href="Packages/a/apr-util-odbc-1.6.1-6.el8.x86_64.rpm"/>
+  <format>
+    <rpm:license>ASL 2.0</rpm:license>
+    <rpm:vendor>AlmaLinux</rpm:vendor>
+    <rpm:group>Development/Libraries</rpm:group>
+    <rpm:buildhost>192-168-246-180.atm.cloudlinux.com</rpm:buildhost>
+    <rpm:sourcerpm>apr-util-1.6.1-6.el8.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="4504" end="19900"/>
+    <rpm:provides>
+      <rpm:entry name="apr-util-odbc(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+      <rpm:entry name="apr-util-odbc" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libc.so.6(GLIBC_2.14)(64bit)"/>
+      <rpm:entry name="rtld(GNU_HASH)"/>
+      <rpm:entry name="libpthread.so.0()(64bit)"/>
+      <rpm:entry name="libodbc.so.2()(64bit)"/>
+      <rpm:entry name="apr-util(x86-64)" flags="EQ" epoch="0" ver="1.6.1" rel="6.el8"/>
+    </rpm:requires>
+  </format>
+</package>
+</metadata>
diff --git a/tests/documents/rpm_primary2.xml b/tests/documents/rpm_primary2.xml
new file mode 100644
index 0000000..fa9ce6c
--- /dev/null
+++ b/tests/documents/rpm_primary2.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata xmlns="http://linux.duke.edu/metadata/common"
+    xmlns:rpm="http://linux.duke.edu/metadata/rpm" packages="4">
+    <package type="rpm">
+        <name>complex-package</name>
+        <arch>x86_64</arch>
+        <version epoch="1" ver="2.3.4" rel="5.el8"/>
+        <checksum type="sha256" pkgid="YES">bbb7b0e9350a0f75b923bdd0ef4f9af39765c668a3e70bfd3486ea9f0f618aaf</checksum>
+        <summary>A package for exercising many different features of RPM metadata</summary>
+        <description>Complex package</description>
+        <packager>Michael Bluth</packager>
+        <url>http://bobloblaw.com</url>
+        <time file="1627052744" build="1627052743"/>
+        <size package="8680" installed="117" archive="932"/>
+        <location href="complex-package-2.3.4-5.el8.x86_64.rpm"/>
+        <format>
+            <rpm:license>MPLv2</rpm:license>
+            <rpm:vendor>Bluth Company</rpm:vendor>
+            <rpm:group>Development/Tools</rpm:group>
+            <rpm:buildhost>localhost</rpm:buildhost>
+            <rpm:sourcerpm>complex-package-2.3.4-5.el8.src.rpm</rpm:sourcerpm>
+            <rpm:header-range start="4504" end="8413"/>
+            <rpm:provides>
+                <rpm:entry name="/usr/bin/ls"/>
+                <rpm:entry name="complex-package" flags="EQ" epoch="1" ver="2.3.4" rel="5.el8"/>
+                <rpm:entry name="complex-package(x86-64)" flags="EQ" epoch="1" ver="2.3.4" rel="5.el8"/>
+                <rpm:entry name="laughter" flags="EQ" epoch="0" ver="33"/>
+                <rpm:entry name="narration(ronhoward)"/>
+            </rpm:provides>
+            <rpm:requires>
+                <rpm:entry name="/usr/bin/bash"/>
+                <rpm:entry name="/usr/sbin/useradd" pre="1"/>
+                <rpm:entry name="arson" flags="GE" epoch="0" ver="1.0.0" rel="1"/>
+                <rpm:entry name="fur" flags="LE" epoch="0" ver="2"/>
+                <rpm:entry name="staircar" flags="LE" epoch="0" ver="99.1" rel="3"/>
+            </rpm:requires>
+            <rpm:conflicts>
+                <rpm:entry name="foxnetwork" flags="GT" epoch="0" ver="5555"/>
+            </rpm:conflicts>
+            <rpm:obsoletes>
+                <rpm:entry name="bluemangroup" flags="LT" epoch="0" ver="32.1" rel="0"/>
+                <rpm:entry name="cornballer" flags="LT" epoch="0" ver="444"/>
+            </rpm:obsoletes>
+            <rpm:suggests>
+                <rpm:entry name="(bobloblaw &gt;= 1.1 if maritimelaw else anyone &lt; 0.5.1-2)"/>
+                <rpm:entry name="(dove and return)"/>
+                <rpm:entry name="(job or money &gt; 9000)"/>
+            </rpm:suggests>
+            <rpm:enhances>
+                <rpm:entry name="(bananas or magic)"/>
+            </rpm:enhances>
+            <rpm:recommends>
+                <rpm:entry name="((hiding and attic) if light-treason)"/>
+                <rpm:entry name="GeneParmesan(PI)"/>
+                <rpm:entry name="yacht" flags="GT" epoch="9" ver="11.0" rel="0"/>
+            </rpm:recommends>
+            <rpm:supplements>
+                <rpm:entry name="((hiding and illusion) unless alliance-of-magicians)"/>
+                <rpm:entry name="comedy" flags="EQ" epoch="0" ver="11.1" rel="4"/>
+            </rpm:supplements>
+            <file>/etc/complex/pkg.cfg</file>
+            <file>/usr/bin/complex_a</file>
+        </format>
+    </package>
+    <package type="rpm">
+        <name>rpm-empty</name>
+        <arch>x86_64</arch>
+        <version epoch="0" ver="0" rel="0"/>
+        <checksum type="sha256" pkgid="YES">90fbba546300f507473547f33e229ee7bad94bbbe6e84b21d485e8e43b5f1132</checksum>
+        <summary>""</summary>
+        <description></description>
+        <packager></packager>
+        <url></url>
+        <time file="1625930845" build="1615686424"/>
+        <size package="6005" installed="0" archive="124"/>
+        <location href="rpm-empty-0-0.x86_64.rpm"/>
+        <format>
+            <rpm:license>LGPL</rpm:license>
+            <rpm:vendor></rpm:vendor>
+            <rpm:group>Unspecified</rpm:group>
+            <rpm:buildhost>localhost</rpm:buildhost>
+            <rpm:sourcerpm>rpm-empty-0-0.src.rpm</rpm:sourcerpm>
+            <rpm:header-range start="4504" end="5961"/>
+            <rpm:provides>
+                <rpm:entry name="rpm-empty" flags="EQ" epoch="0" ver="0" rel="0"/>
+                <rpm:entry name="rpm-empty(x86-64)" flags="EQ" epoch="0" ver="0" rel="0"/>
+            </rpm:provides>
+        </format>
+    </package>
+    <package type="rpm">
+        <name>rpm-with-invalid-chars</name>
+        <arch>noarch</arch>
+        <version epoch="0" ver="1" rel="1.fc33"/>
+        <checksum type="sha256" pkgid="YES">64f1444f8e86a9ae6accdc2c4b12cb4a87fb2414c0998df461a8623a52eb3cc4</checksum>
+        <summary>An RPM file with invalid characters in its description.</summary>
+        <description>This RPM that contains XML-illegal characters such as ampersand &amp; and less-than &lt; greater-than &gt; in its &lt;/description&gt;.
+These must be escaped in the final XML metadata. The XML spec does not strictly require escaping 'single' or "double" quotes
+within text content, and not all XML libraries do so. However, it is generally recommended.</description>
+        <packager></packager>
+        <url>https://github.com/dralley/rpmrepo_rs/</url>
+        <time file="1625930845" build="1617418325"/>
+        <size package="6489" installed="0" archive="124"/>
+        <location href="rpm-with-invalid-chars-1-1.fc33.noarch.rpm"/>
+        <format>
+            <rpm:license>Public Domain</rpm:license>
+            <rpm:vendor></rpm:vendor>
+            <rpm:group>Unspecified</rpm:group>
+            <rpm:buildhost>localhost</rpm:buildhost>
+            <rpm:sourcerpm>rpm-with-invalid-chars-1-1.fc33.src.rpm</rpm:sourcerpm>
+            <rpm:header-range start="4504" end="6445"/>
+            <rpm:provides>
+                <rpm:entry name="rpm-with-invalid-chars" flags="EQ" epoch="0" ver="1" rel="1.fc33"/>
+            </rpm:provides>
+        </format>
+    </package>
+    <package type="rpm">
+        <name>rpm-with-non-ascii</name>
+        <arch>noarch</arch>
+        <version epoch="0" ver="1" rel="1.fc33"/>
+        <checksum type="sha256" pkgid="YES">957de8a966af8fe8e55102489099d8b20bbecc23954c8c2bd88fb59625260393</checksum>
+        <summary>An RPM file with non-ascii characters in its metadata.</summary>
+        <description>This file contains unicode characters and should be encoded as UTF-8. The
+following code points are all outside the "Basic Latin (ASCII)" code point
+block:
+
+* U+0080: 
+* U+0100: Ā
+* U+0180: ƀ
+* U+0250: ɐ
+* U+02B0: ʰ
+* U+0041 0x0300: À
+* U+0370: Ͱ
+
+See: http://www.unicode.org/charts/</description>
+        <packager></packager>
+        <url>https://github.com/dralley/rpmrepo_rs/</url>
+        <time file="1625930845" build="1615686425"/>
+        <size package="6433" installed="0" archive="124"/>
+        <location href="rpm-with-non-ascii-1-1.fc33.noarch.rpm"/>
+        <format>
+            <rpm:license>Public Domain</rpm:license>
+            <rpm:vendor></rpm:vendor>
+            <rpm:group>Unspecified</rpm:group>
+            <rpm:buildhost>localhost</rpm:buildhost>
+            <rpm:sourcerpm>rpm-with-non-ascii-1-1.fc33.src.rpm</rpm:sourcerpm>
+            <rpm:header-range start="4504" end="6389"/>
+            <rpm:provides>
+                <rpm:entry name="rpm-with-non-ascii" flags="EQ" epoch="0" ver="1" rel="1.fc33"/>
+            </rpm:provides>
+        </format>
+    </package>
+</metadata>
diff --git a/tests/sample_rss.xml b/tests/documents/sample_rss.xml
similarity index 100%
rename from tests/sample_rss.xml
rename to tests/documents/sample_rss.xml
diff --git a/tests/test.rs b/tests/test.rs
index a47d301..36ed5df 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -9,7 +9,7 @@ use pretty_assertions::assert_eq;
 
 #[test]
 fn test_sample() {
-    let src: &[u8] = include_bytes!("sample_rss.xml");
+    let src: &[u8] = include_bytes!("documents/sample_rss.xml");
     let mut buf = Vec::new();
     let mut r = Reader::from_reader(src);
     let mut count = 0;
@@ -264,7 +264,8 @@ fn line_score() {
         inning: String,
     }
 
-    let res: LineScoreData = quick_xml::de::from_str(include_str!("linescore.xml")).unwrap();
+    let res: LineScoreData =
+        quick_xml::de::from_str(include_str!("documents/linescore.xml")).unwrap();
 
     let expected = LineScoreData {
         game_pk: 239575,
@@ -376,7 +377,7 @@ fn players() {
         id: u32,
     }
 
-    let res: Game = quick_xml::de::from_str(include_str!("players.xml")).unwrap();
+    let res: Game = quick_xml::de::from_str(include_str!("documents/players.xml")).unwrap();
 
     let expected = Game {
         teams: vec![