Scala XML – Einfache XML Verarbeitung Tobias Neumann | ITGAIN Consulting
XML Literale,  Embedded Expressions
XML Literale Scala hat direkte XML-Sprachunterstütung XML Literale sind &quot;first-class&quot; val x = <itemNo>1234</itemNo> Ergebnis ist vom Typ Elem val x = Elem(null,&quot;itemNo&quot;,null,TopScope, Text(1234))
XML Element case class  Elem ( val override  prefix  : java.lang.String, val  label  : java.lang.String,  val override  attributes  : MetaData,  val override  scope  : NamespaceBinding,  val  child  : Node*)  extends Node
Attribute Attribute im XML-Literal val order = <order prio=&quot;high&quot;></order> Attribute sind eine verkettete Liste von (Un)prexfixedAttribute val attr=new UnprefixedAttribute(&quot;prio&quot;,&quot;high&quot;,Null) Attribute in Elem Elem(null,&quot;order&quot;,attr,TopScope) PrefixedAttribute für Namespaces
Namespaces Namespaces im XML-Literal val order = <o:order xmlns:o=&quot;http://company.com&quot;></o:order> NamespaceBinding val scope=new NamespaceBinding(&quot;o&quot;,&quot;http://company.com&quot;, TopScope) Namespace in Elem Elem(&quot;o&quot;,&quot;order&quot;,null,scope)
Übersicht XML Klassen Node: Superklasse aller XML-Nodes NodeSeq: Sequence von Nodes, jede Node erbt von NodeSeq Elem: Elemente werden dargestellt mit Elem und Text Elem und Text sind Case Classes   Pattern Matching NodeSeq Node Elem
Embedded Expressions Scala Code ist innerhalb des XML Literals ausführbar: <quantity> { 3+5 } </quantity> val quantity = 24 <order prio= { if (quantity > 10) &quot;high&quot; else &quot;normal&quot; } > <itemNo>123</itemNo> <quantity> { quantity } </quantity> </order>
Embedded Expressions Wenn Ergebnis vom Typ Node oder NodeSeq ist, wird dieses direkt eingefügt val l = (&quot;1414&quot;,&quot;5&quot;) :: (&quot;6262&quot;,&quot;3&quot;) :: (&quot;1212&quot;,&quot;1&quot;) :: Nil <order> { l.map(p => <item> <itemNo>{p._1}</itemNo> <quantity>{p._2}</quantity></item> ) } </order>    Beispiel 1
Serialisierung Einfache Serialisierung mit Embedded Expressions case class item(val itemNo, val quantity) { def toXML= {   <item><itemno> { itemno } </itemNo>   <quantity> { quantity } </quantity></item> } }    Beispiel 2
XML Laden und Speichern XML.load Lädt XML aus Reader, InputStream, etc. XML.loadFile Lädt XML direkt aus Datei XML.save Speichert XML in Datei XML.saveFull Speichert XML mit Angabe Encoding und Doctype
Pattern matching
Pattern matching Pattern matching auf XML Literale {} ist hier kein Ausdruck, sondern das Pattern n match { case <itemNo>{itemno}</itemNo> =>   println (&quot;Artikelnummer: &quot; + itemno) case <quantity>{quantity}</quantity> =>   println (&quot;Anzahl: &quot; + quantity) case _ => }    Beipiel 3
Pattern matching Alle Möglichkeiten des Pattern Matching Binden von Variablen mit @ Wildcards mit _ und _* case <order>order @ _*</order> => order.foreach(printNode)
Update/Add Nodes Pattern matching kann gut genutzt werden für Updaten und Hinzufügen von Node def addNode(n: Node, newNode: Node): Node = n match { case <order>{oldNode @ _*}</order> => <order>{oldNode}{newNode}</order> }    Beipiel 4
XSLT-like Transformation Pattern matching bietet XSLT-ähnliche Transformation von XML Definition eines Templates case <order>{x @ _*}</order> => <html>   <head><title>Bestellliste</title></head>   <body>{transform(x)}</body>   </html>  case <item>{x @ _*}</item> =>   <p>{transform(x)}</p>  case <itemNo>{x @ _*}</itemNo> =>   <b>Artikel {x}: </b>    Beispiel 5
Xpath-like Queries
XPath-like Queries Die Methoden \ und \\ bieten Xpath-ähnliche Abfragen auf Nodes Ergebnis ist wieder vom Typ NodeSeq XPath Scala Direkt unterge- / \ ordneter Knoten /item \ &quot;item&quot; Untergeordneter // \\ Knoten //quantity \\ &quot;quantity&quot; Attribute @ @ //@prio \\ &quot;@prio&quot;
Deserialisierung Deserisalisierung mit XPath: def fromXML(n: Node): Item = { new Item(n \ &quot;itemNo&quot; text, n \ &quot;quantity&quot; text)  } val n = <item><itemNo>5</itemNo> <quantity>5</quantity><item> val item = Item.fromXML(n) item: Item = Item(3,5)    Beispiel 2a
Transformation Transformation mit XPath def transformOrderlist(node: Node): Node = {  def transform(ns: NodeSeq) : NodeSeq =   for (n <- ns \ &quot;item&quot;) yield    <p><b>Artikel  { n \ &quot;itemNo&quot; text } : </b>   { n \ &quot;quantity&quot; text }  mal</p>   {<html><head><title>Bestellliste</title></head>  <body><h1>Bestellliste:</h1>   { transform(node) } </body></html>} }    Beispiel 6
XML-Validierung XML.load() lädt immer die eingebundene DTD/XSD Datei Offensichtlich wird aber nicht validiert! Implementierung des ValidatingMarkupHandlers führt zu Fehlern beim Lesen der DTD  Work-around: Wrapping des SAX Parsers
Beispiel: Scala XML in Lift Verwendung von XML-Literalen in Lift: <lift:surround with=&quot;default&quot; at=&quot;content&quot;> <h2>Welcome to your project!</h2> <p> <lift:helloJax.hello /> </p> </lift:surround> class HelloJax { def hello = <span>Welcome to JAX at {new _root_.java.util.Date}</span> }
Scala vs. Java Code reduction Java DocumentBuilderFactory domFactory =   DocumentBuilderFactory. newInstance(); DocumentBuilder builder =   domFactory.newDocumentBuilder(); Document doc = builder.parse(&quot;order.xml&quot;); Scala val doc = XML.loadFile(&quot;order.xml&quot;);
Scala vs. Java Java XPathExpression xe = xpath.compile  (&quot;//order/item&quot;); NodeList nodes = (NodeList)  xe.evaluate(doc,XPathConstants. NODESET); Scala val nodes = doc \\ &quot;order&quot; \ &quot;item&quot;
Fazit Pros: Viele Vorteile durch XML-Unterstützung auf syntaktischer Ebene Verschiedene Techniken Case classes/pattern matching XPath Cons: XML-Validierung Dokumentation
Literatur & Links Scala XML (draft), Emir Burak http://burak.emir.googlepages.com/ scalaxbook.docbk.html  Programming in Scala, Martin Odersky et al Why simple XML processing is so painful in Java?, Francois Armand http://fanf42.blogspot.com/2009/08/why-simple-xml-processing-is-so-painful.html XSD Validation in Scala, Sean Wellington http://sean8223.blogspot.com/2009/09/xsd-validation-in-scala.html
Vielen Dank Tobias Neumann ITGAIN Consulting GmbH [email_address] www.itgain.de

Scala XML

  • 1.
    Scala XML –Einfache XML Verarbeitung Tobias Neumann | ITGAIN Consulting
  • 2.
    XML Literale, Embedded Expressions
  • 3.
    XML Literale Scalahat direkte XML-Sprachunterstütung XML Literale sind &quot;first-class&quot; val x = <itemNo>1234</itemNo> Ergebnis ist vom Typ Elem val x = Elem(null,&quot;itemNo&quot;,null,TopScope, Text(1234))
  • 4.
    XML Element caseclass Elem ( val override prefix : java.lang.String, val label : java.lang.String, val override attributes : MetaData, val override scope : NamespaceBinding, val child : Node*) extends Node
  • 5.
    Attribute Attribute imXML-Literal val order = <order prio=&quot;high&quot;></order> Attribute sind eine verkettete Liste von (Un)prexfixedAttribute val attr=new UnprefixedAttribute(&quot;prio&quot;,&quot;high&quot;,Null) Attribute in Elem Elem(null,&quot;order&quot;,attr,TopScope) PrefixedAttribute für Namespaces
  • 6.
    Namespaces Namespaces imXML-Literal val order = <o:order xmlns:o=&quot;http://company.com&quot;></o:order> NamespaceBinding val scope=new NamespaceBinding(&quot;o&quot;,&quot;http://company.com&quot;, TopScope) Namespace in Elem Elem(&quot;o&quot;,&quot;order&quot;,null,scope)
  • 7.
    Übersicht XML KlassenNode: Superklasse aller XML-Nodes NodeSeq: Sequence von Nodes, jede Node erbt von NodeSeq Elem: Elemente werden dargestellt mit Elem und Text Elem und Text sind Case Classes  Pattern Matching NodeSeq Node Elem
  • 8.
    Embedded Expressions ScalaCode ist innerhalb des XML Literals ausführbar: <quantity> { 3+5 } </quantity> val quantity = 24 <order prio= { if (quantity > 10) &quot;high&quot; else &quot;normal&quot; } > <itemNo>123</itemNo> <quantity> { quantity } </quantity> </order>
  • 9.
    Embedded Expressions WennErgebnis vom Typ Node oder NodeSeq ist, wird dieses direkt eingefügt val l = (&quot;1414&quot;,&quot;5&quot;) :: (&quot;6262&quot;,&quot;3&quot;) :: (&quot;1212&quot;,&quot;1&quot;) :: Nil <order> { l.map(p => <item> <itemNo>{p._1}</itemNo> <quantity>{p._2}</quantity></item> ) } </order>  Beispiel 1
  • 10.
    Serialisierung Einfache Serialisierungmit Embedded Expressions case class item(val itemNo, val quantity) { def toXML= { <item><itemno> { itemno } </itemNo> <quantity> { quantity } </quantity></item> } }  Beispiel 2
  • 11.
    XML Laden undSpeichern XML.load Lädt XML aus Reader, InputStream, etc. XML.loadFile Lädt XML direkt aus Datei XML.save Speichert XML in Datei XML.saveFull Speichert XML mit Angabe Encoding und Doctype
  • 12.
  • 13.
    Pattern matching Patternmatching auf XML Literale {} ist hier kein Ausdruck, sondern das Pattern n match { case <itemNo>{itemno}</itemNo> => println (&quot;Artikelnummer: &quot; + itemno) case <quantity>{quantity}</quantity> => println (&quot;Anzahl: &quot; + quantity) case _ => }  Beipiel 3
  • 14.
    Pattern matching AlleMöglichkeiten des Pattern Matching Binden von Variablen mit @ Wildcards mit _ und _* case <order>order @ _*</order> => order.foreach(printNode)
  • 15.
    Update/Add Nodes Patternmatching kann gut genutzt werden für Updaten und Hinzufügen von Node def addNode(n: Node, newNode: Node): Node = n match { case <order>{oldNode @ _*}</order> => <order>{oldNode}{newNode}</order> }  Beipiel 4
  • 16.
    XSLT-like Transformation Patternmatching bietet XSLT-ähnliche Transformation von XML Definition eines Templates case <order>{x @ _*}</order> => <html> <head><title>Bestellliste</title></head> <body>{transform(x)}</body> </html> case <item>{x @ _*}</item> => <p>{transform(x)}</p> case <itemNo>{x @ _*}</itemNo> => <b>Artikel {x}: </b>  Beispiel 5
  • 17.
  • 18.
    XPath-like Queries DieMethoden \ und \\ bieten Xpath-ähnliche Abfragen auf Nodes Ergebnis ist wieder vom Typ NodeSeq XPath Scala Direkt unterge- / \ ordneter Knoten /item \ &quot;item&quot; Untergeordneter // \\ Knoten //quantity \\ &quot;quantity&quot; Attribute @ @ //@prio \\ &quot;@prio&quot;
  • 19.
    Deserialisierung Deserisalisierung mitXPath: def fromXML(n: Node): Item = { new Item(n \ &quot;itemNo&quot; text, n \ &quot;quantity&quot; text) } val n = <item><itemNo>5</itemNo> <quantity>5</quantity><item> val item = Item.fromXML(n) item: Item = Item(3,5)  Beispiel 2a
  • 20.
    Transformation Transformation mitXPath def transformOrderlist(node: Node): Node = { def transform(ns: NodeSeq) : NodeSeq = for (n <- ns \ &quot;item&quot;) yield <p><b>Artikel { n \ &quot;itemNo&quot; text } : </b> { n \ &quot;quantity&quot; text } mal</p> {<html><head><title>Bestellliste</title></head> <body><h1>Bestellliste:</h1> { transform(node) } </body></html>} }  Beispiel 6
  • 21.
    XML-Validierung XML.load() lädtimmer die eingebundene DTD/XSD Datei Offensichtlich wird aber nicht validiert! Implementierung des ValidatingMarkupHandlers führt zu Fehlern beim Lesen der DTD Work-around: Wrapping des SAX Parsers
  • 22.
    Beispiel: Scala XMLin Lift Verwendung von XML-Literalen in Lift: <lift:surround with=&quot;default&quot; at=&quot;content&quot;> <h2>Welcome to your project!</h2> <p> <lift:helloJax.hello /> </p> </lift:surround> class HelloJax { def hello = <span>Welcome to JAX at {new _root_.java.util.Date}</span> }
  • 23.
    Scala vs. JavaCode reduction Java DocumentBuilderFactory domFactory = DocumentBuilderFactory. newInstance(); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(&quot;order.xml&quot;); Scala val doc = XML.loadFile(&quot;order.xml&quot;);
  • 24.
    Scala vs. JavaJava XPathExpression xe = xpath.compile (&quot;//order/item&quot;); NodeList nodes = (NodeList) xe.evaluate(doc,XPathConstants. NODESET); Scala val nodes = doc \\ &quot;order&quot; \ &quot;item&quot;
  • 25.
    Fazit Pros: VieleVorteile durch XML-Unterstützung auf syntaktischer Ebene Verschiedene Techniken Case classes/pattern matching XPath Cons: XML-Validierung Dokumentation
  • 26.
    Literatur & LinksScala XML (draft), Emir Burak http://burak.emir.googlepages.com/ scalaxbook.docbk.html Programming in Scala, Martin Odersky et al Why simple XML processing is so painful in Java?, Francois Armand http://fanf42.blogspot.com/2009/08/why-simple-xml-processing-is-so-painful.html XSD Validation in Scala, Sean Wellington http://sean8223.blogspot.com/2009/09/xsd-validation-in-scala.html
  • 27.
    Vielen Dank TobiasNeumann ITGAIN Consulting GmbH [email_address] www.itgain.de