k47.cz
mastodon twitter RSS
bandcamp explorer 0xDEADBEEF
komentáře článku 

Srovnání Scala.xml, Anti-xml a XPath



Text komentáře


v6ak (2012-05-03 11:25)
Type safety - není to až takový rozdíl u těchto tří knihoven, ale pokud bychom mapovali XML na objekty, bylo by to jinde...

Nevím, co mi přesně na XPath vadí. Asi to, že mu nemůžu snadno předat třeba string zvenku, aniž bych se musel bát injekce. (Neříkám, že to nejde, je to jen otázka náročnosti.) A hlavně mi asi přijdou tato DSLka přirozenější, což je ale subjektivní.


v6ak (2012-10-20 14:23)
Tak už lépe chápu vztah k XPath. Zkusil jsem AntiXML. Potřeboval jsem si dopsat DSL, abych mohl udělat query podle id nebo class v tomto stylu:
/--- code scala
val main = html \\ "div"##"main-content"
val summary = main \ "div"@@("class", "summary") \ "h2" \\ text map {_.trim} mkString ":"
\---


kaja47 (2012-10-25 09:54)
[1011] To je pěkný. Já jsem si do DSL doplnil dva obecné selektory (které mají stejnou precedenci jako `\` a `\\`): `\?` jako alias pro filter a `\@`, který vybírá atributy.

/---
val main = html \\ "div" \? (_ \@ "id" == "main-content")
val summary = main \ "div" \? (_ \@ "class" == "summary") \ "h2" \\ text map {_.trim} mkString ":"
\---


v6ak (2012-10-28 11:05)
Zatím jsem to řešil takto:
@@ - pro výběr podle atributu
#? - pro výběr podle id, vrací Option
## - pro výběr podle id, vrací element nebo háže výjimku

Dávám jako public domain, akorát nevím, podle čeho pojmenovávat konvertovací funkci:
/--- code Scala
implicit def easyAntiXmlAccess(el: antixml.Group[antixml.Elem]) = new {
def @@ (name: String, f: String=>Boolean): antixml.Group[antixml.Elem] = el filter {_.attrs.get(name) filter f isDefined}
def @@ (name: String, value: String): antixml.Group[antixml.Elem] = this @@ (name, _==value)
def #? (id: String) = this @@ ("id", id) headOption
def ## (id: String) = this #? id get
}
\---

Vím, že asi konstrukce s `new {...}` není efektivní, asi to vynucuje použití Reflection API. Zatím jsem to neřešil, ale bude stačit použít pojmenovanou třídu. Nebo aspoň pojmenované rozhraní.


v6ak (2012-10-28 11:06)
Škoda, že tu není náhled. Tak začátek ještě jednou:

Zatím jsem to řešil takto:

* @@ – pro výběr podle atributu
* #? – pro výběr podle id, vrací Option
* ## – pro výběr podle id, vrací element nebo háže výjimku


v6ak (2012-11-07 20:05)
Tak další pokusy. AntiXML začalo při parsování házet StackOverflowError, přešel jsem na scala.xml. Kód zůstal skoro stejný. Řešil jsem jen asi tři věci:

* Elem -> Node
* Group -> NodeSeq
* (_:Node).attrs -> (_:Node).attributes.asAttrMap (pomocí automatické konverze)

Víceméně jsem přepsal knihovničku. Momentálně nemám moc motivaci používat AntiXML.


kaja47 (2012-11-08 00:44)
[1017] Stack overflow je způsobený chybou při parsování HTML a vyskytuje se jenom ve verzi 0.3. 0.4 je už v pořádku + je mnohem rychlejší, protože všechny selekce jsou líné.


v6ak (2012-11-08 12:43)
Aha, díky za info. Použil jsem poslední stabilní verzi, tj. 0.3.

To ale znamená, že obojí bude pro mě zhruba stejně použitelné, až na výkon (hraje pro AntiXML) a nativní XML literály (zatím hraje pro scala.xml, v budoucnu se možná změní). Jo vlastně, úpravy atributů (např. transformace SVG) byly trošku PITA se scala.xml: https://gist.github.com/4038281#L120

BTW: Nemáš něco bližšího k tomu StackOverflowError? Našel jsem jen jedno vyhnilé issue na Githubu. Zajímavé, že se mi to stávalo i při konverzi ze scala.xml do Anti-XML (via ElemConvertable). Jako by se to převádělo přes String. Je ale fakt, že včera mě to StackOverflowError dost namíchlo - kromě toho, že jsem nevěděl, odkud pochází (JVM ořezala stacktrace), přišlo to nečekaně při minimálních úpravách -- skript byl hotov, ale >20MiB JAR (vč. závislostí) se mi zdál moc, tak jsem začal Proguardit. A při tom jsem akorát odstraňoval konstrukce `new {}`, abych se vyhnul Reflection. A najednou se začal objevovat onen StackOverflowError. Ale jen při běhu z jar (sbt assembly i sbt proguard), ne při běhu přes sbt run.


píše k47, ascii@k47.cz