parse first paragraph of wuchergesetz

This commit is contained in:
2023-11-04 10:07:43 +01:00
parent 62b0e1e69d
commit 3fa97cca34
8 changed files with 814 additions and 1 deletions

View File

@ -1,7 +1,9 @@
use std::io;
mod law;
mod par;
#[derive(Debug)]
pub struct Error {
msg: String,
}
@ -27,7 +29,15 @@ impl From<serde_json::Error> for Error {
}
}
}
impl From<roxmltree::Error> for Error {
fn from(value: roxmltree::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
fn main() {
law::parse(10001905);
//law::parse(10001905);
par::parse("https://www.ris.bka.gv.at/Dokumente/Bundesnormen/NOR12025172/NOR12025172.xml");
}

14
src/par/mod.rs Normal file
View File

@ -0,0 +1,14 @@
mod parser;
use crate::{par::parser::Risdok, Error};
fn fetch_page(url: &str) -> Result<String, Error> {
Ok(ureq::get(url).call()?.into_string()?)
}
pub(crate) fn parse(url: &str) -> Result<(), Error> {
let xml = fetch_page(url)?;
let risdok = Risdok::from_str(&xml)?;
Ok(())
}

286
src/par/parser.rs Normal file
View File

@ -0,0 +1,286 @@
use roxmltree::Node;
use crate::Error;
#[derive(Debug, PartialEq)]
pub(crate) struct Risdok {
metadaten: Metadaten,
nutzdaten: Nutzdaten,
layoutdaten: Layoutdaten,
}
impl Risdok {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "risdok");
let mut c = n.children();
let ret = Self {
metadaten: Metadaten::parse(c.next().unwrap()),
nutzdaten: Nutzdaten::parse(c.next().unwrap()),
layoutdaten: Layoutdaten::parse(c.next().unwrap()),
};
assert_eq!(c.next(), None);
ret
}
pub(crate) fn from_str(xml: &str) -> Result<Self, Error> {
let doc = roxmltree::Document::parse(&xml)?;
let root = doc.root();
assert_eq!(root.children().into_iter().count(), 1);
Ok(Self::parse(root.children().next().unwrap()))
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Metadaten;
impl Metadaten {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "metadaten");
assert_eq!(n.children().next(), None);
Self {}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Nutzdaten {
abschnitt: Abschnitt,
}
impl Nutzdaten {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "nutzdaten");
let mut c = n.children();
let ret = Self {
abschnitt: Abschnitt::parse(c.next().unwrap()),
};
assert_eq!(c.next(), None);
ret
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Abschnitt {
ueberschriftPara: Option<UeberschriftPara>,
absatz: AbsatzAbs,
}
impl Abschnitt {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "abschnitt");
let mut c = n.children().peekable();
Kzinhalt::parse(c.next().unwrap());
Kzinhalt::parse(c.next().unwrap());
Fzinhalt::parse(c.next().unwrap());
Fzinhalt::parse(c.next().unwrap());
// Skip all UeberschriftTitle and Absatz
loop {
match c.peek() {
Some(child) => {
if UeberschriftTitle::test(child) {
c.next();
continue;
}
if Absatz::test(child) {
c.next();
continue;
}
break;
}
None => break,
}
}
let mut ueberschriftPara = None;
if let Some(child) = c.peek() {
if UeberschriftPara::test(child) {
ueberschriftPara = Some(UeberschriftPara::parse(c.next().unwrap()))
}
}
let absatz = AbsatzAbs::parse(c.next().unwrap());
// Skip all UeberschriftTitle and Absatz
loop {
match c.peek() {
Some(child) => {
if UeberschriftTitle::test(child) {
c.next();
continue;
}
if Absatz::test(child) {
c.next();
continue;
}
break;
}
None => break,
}
}
assert_eq!(c.next(), None);
Self {
ueberschriftPara,
absatz,
}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct AbsatzAbs {
gldsym: String,
content: String,
}
impl AbsatzAbs {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "absatz");
assert_eq!(n.attribute("typ").unwrap(), "abs");
let mut c = n.children();
let ret = Self {
gldsym: Leaf::parse(c.next().unwrap(), "gldsym".into()).replace("\u{a0}", " "),
content: c.next().unwrap().text().unwrap().trim().into(),
};
assert_eq!(c.next(), None);
ret
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Leaf {
content: String,
}
impl Leaf {
pub(crate) fn parse(n: Node, name: String) -> String {
assert!(n.tag_name().name() == name);
assert_eq!(n.children().into_iter().count(), 1);
n.text().unwrap().into()
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Absatz {
content: String,
}
impl Absatz {
pub(crate) fn test(n: &Node) -> bool {
n.tag_name().name() == "absatz"
}
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "absatz");
Self {
content: n.text().unwrap().into(),
}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct UeberschriftPara {
content: String,
}
impl UeberschriftPara {
pub(crate) fn test(n: &Node) -> bool {
n.tag_name().name() == "ueberschrift" && n.attribute("typ").unwrap() == "para"
}
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "ueberschrift");
assert_eq!(n.attribute("typ").unwrap(), "para");
Self {
content: n.text().unwrap().into(),
}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct UeberschriftTitle;
impl UeberschriftTitle {
fn test(n: &Node) -> bool {
n.tag_name().name() == "ueberschrift" && n.attribute("typ").unwrap() == "titel"
}
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "ueberschrift");
assert_eq!(n.attribute("typ").unwrap(), "titel");
//TODO parse if necessary
Self {}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Kzinhalt;
impl Kzinhalt {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "kzinhalt");
//TODO parse if necessary
Self {}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Fzinhalt;
impl Fzinhalt {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "fzinhalt");
//TODO parse if necessary
Self {}
}
}
#[derive(Debug, PartialEq)]
pub(crate) struct Layoutdaten;
impl Layoutdaten {
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "layoutdaten");
assert_eq!(n.children().next(), None);
Self {}
}
}
#[cfg(test)]
mod tests {
use std::{fs::File, io::Read};
use super::*;
#[test]
fn deserialize_wucher1_success() {
let mut file = File::open("data/par/wucher1.xml").unwrap();
let mut xml = String::new();
file.read_to_string(&mut xml).unwrap();
let risdok = Risdok::from_str(&xml);
if risdok.is_err() {
println!("{:#?}", risdok.as_ref().err());
}
assert!(risdok.is_ok());
let abschnitt = risdok.unwrap().nutzdaten.abschnitt;
assert_eq!(
abschnitt.ueberschriftPara.unwrap().content,
"Nichtigkeit eines wucherischen Vertrages."
);
assert_eq!(abschnitt.absatz, AbsatzAbs {gldsym: "§ 1.".into(), content: "Ein Vertrag ist nichtig, wenn jemand den Leichtsinn, die Zwangslage, Verstandesschwäche, Unerfahrenheit oder Gemütsaufregung eines anderen dadurch ausbeutet, daß er sich oder einem Dritten für eine Leistung eine Gegenleistung versprechen oder gewähren läßt, deren Vermögenswert zu dem Werte seiner Leistung in auffallendem Mißverhältnis steht.".into()});
}
}