package com.googlecode.totallylazy.xml.streaming;
import com.googlecode.totallylazy.Maps;
import com.googlecode.totallylazy.Sequence;
import com.googlecode.totallylazy.xml.Xml;
import com.googlecode.totallylazy.functions.TimeReport;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Node;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.StringReader;
import java.util.Map;
import static com.googlecode.totallylazy.Assert.assertThat;
import static com.googlecode.totallylazy.functions.Functions.option;
import static com.googlecode.totallylazy.functions.Functions.or;
import static com.googlecode.totallylazy.Maps.map;
import static com.googlecode.totallylazy.Pair.pair;
import static com.googlecode.totallylazy.predicates.Predicates.is;
import static com.googlecode.totallylazy.Sequences.sequence;
import static com.googlecode.totallylazy.xml.streaming.XPath.attribute;
import static com.googlecode.totallylazy.xml.streaming.XPath.child;
import static com.googlecode.totallylazy.xml.streaming.XPath.descendant;
import static com.googlecode.totallylazy.xml.streaming.XPath.name;
import static com.googlecode.totallylazy.xml.streaming.XPath.xpath;
import static com.googlecode.totallylazy.xml.streaming.Xml.contexts;
import static com.googlecode.totallylazy.xml.streaming.Xml.nodes;
public class XmlTest {
@Test
public void supportsLocations() throws Exception {
String xml = "<stream><user><first>Dan & Bod</first><dob>1977</dob></user><user><first>Jason</first><dob>1978</dob></user></stream>";
Sequence<Map<String, String>> users = contexts(xml).filter(xpath(descendant(name("user")))).
map(user -> Maps.<String,String>map(user.relative().collect(
xpath(child("first")), field -> pair("name", field.text()),
xpath(child("dob")), field -> pair(field.name(), field.text())
)));
assertThat(users, is(sequence(map("name", "Dan & Bod", "dob", "1977"), map("name", "Jason", "dob", "1978"))));
}
@Test
@Ignore("manual test")
public void xpathIsPrettyFast() throws Exception {
final Sequence<Context> document = contexts("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML+RDFa 1.0//EN\" \"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd\">\n" +
"<xh:html xmlns:xh=\"http://www.w3.org/1999/xhtml\" xmlns:og=\"http://opengraphprotocol.org/schema/\" xml:lang=\"en-GB\" xmlns=\"\">\n" +
"<xh:head><xh:meta content=\"Foo\"/><xh:meta content=\"Bar\"/></xh:head>" +
"<foo>baz</foo>" +
"<og:boo>far</og:boo>" +
"</xh:html>");
TimeReport report = TimeReport.time(1000, () -> {
return document.filter(xpath(descendant("meta"))).map(context -> context.attributes().get("content")).realise();
});
System.out.println(report);
}
@Test
@Ignore("manual test")
public void canLoadCitations() throws Exception {
String path = "an-article-with-many-references.xml";
try (FileReader fileReader = new FileReader(path) ) {
Sequence<Context> document = contexts(new BufferedReader(fileReader));
TimeReport report = TimeReport.time(10, () -> document.
filter(xpath(descendant("Citation"), child("BibArticle"))).
map(citation -> Maps.map(citation.relative().collect(
option(xpath(child("ArticleTitle")), field -> pair("title", field.text())),
option(xpath(child("BibAuthorName")), field -> pair("authors", field.text())),
option(xpath(child("VolumeID")), field -> pair("volume", field.text())),
option(xpath(child("Year")), field -> pair("pubYear", field.text())),
option(xpath(child("JournalTitle")), field -> pair("journalTitle", field.text())),
option(xpath(child(name("Occurrence").and(attribute("Type", is("DOI")))), child("Handle")), field -> pair("doi", field.text()))
))).realise());
System.out.println(report);
}
}
@Test
public void currentlyItEscapesCData() throws Exception {
String xml = "<stream><![CDATA[Hello <> ]]></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "stream");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<stream>Hello <> </stream>"));
}
@Test
public void copiesAllText() throws Exception {
String xml = "<stream>Hello & World</stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "stream");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<stream>Hello & World</stream>"));
}
@Test
public void emptyRoot() throws Exception {
String xml = "<stream/>";
Sequence<Node> stream = nodes(new StringReader(xml), "stream");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<stream/>"));
}
@Test
public void singleItem() throws Exception {
String xml = "<stream><item/></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<item/>"));
}
@Test
public void twoItems() throws Exception {
String xml = "<stream><item id=\"1\"/><item id=\"2\"/></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(2));
assertThat(Xml.asString(stream.first()), is("<item id=\"1\"/>"));
assertThat(Xml.asString(stream.second()), is("<item id=\"2\"/>"));
}
@Test
public void oneItemWithChild() throws Exception {
String xml = "<stream><item><child/></item></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<item><child/></item>"));
}
@Test
public void oneItemWithTwoChildren() throws Exception {
String xml = "<stream><item><child/><child/></item></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.head()), is("<item><child/><child/></item>"));
}
@Test
public void twoItemsWithChild() throws Exception {
String xml = "<stream><item><child/></item><item><child/></item></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(2));
assertThat(Xml.asString(stream.first()), is("<item><child/></item>"));
assertThat(Xml.asString(stream.second()), is("<item><child/></item>"));
}
@Test
public void twoItemsWithTwoChild() throws Exception {
String xml = "<stream><item><child/><child/></item><item><child/><child/></item></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(2));
assertThat(Xml.asString(stream.first()), is("<item><child/><child/></item>"));
assertThat(Xml.asString(stream.second()), is("<item><child/><child/></item>"));
}
@Test
public void supportsAttributes() throws Exception {
String xml = "<stream><item foo='bar'/></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(1));
assertThat(Xml.asString(stream.first()), is("<item foo=\"bar\"/>"));
}
@Test
public void supportsAttributesOnNestedStructures() throws Exception {
String xml = "<stream><item><child foo='bar'/><child/></item><item><child/><child baz='bar'/></item></stream>";
Sequence<Node> stream = nodes(new StringReader(xml), "item");
assertThat(stream.size(), is(2));
assertThat(Xml.asString(stream.first()), is("<item><child foo=\"bar\"/><child/></item>"));
assertThat(Xml.asString(stream.second()), is("<item><child/><child baz=\"bar\"/></item>"));
}
}