EzDevInfo.com

anti-xml

The scala.xml library has some very annoying issues. Time for a clean-room replacement! Anti-XML

Build XML literal containing Anti-XML object

Suppose I have an Anti-XML object, e.g.:

import com.codecommit.antixml._
val child = <child attr="val">...</child>.convert

I want to construct an XML object that contains child as a child:

<parent foo="bar"><foo/><child attr="val">...</child><foo/></parent>

The obvious way would be

val parent : Elem = <parent foo="bar"><foo/>{ child }<foo/></parent>.convert

The problem is that Scala's XML literals don't recognize Anti-XML's objects, so child gets converted to a string, and embedded in parent as a text node:

<parent foo="bar"><foo/>&lt;child attr="val"&gt;...&lt;/child&gt;<foo/></parent>

How can I work around this issue?


Source: (StackOverflow)

Anti-XML scala hides xml attribute

Anti-xml will be the successor xml library in Scala. But I have found something that quirks.

Input

package com.twitter.sample
import com.codecommit.antixml._

object ReadingNamespaceXml extends Application{

  val xml = <tra:route xmlns:tra="trace">
              <spo:id xmlnls:spo="sport">23232322</spo:id>
              <tra:service ref="go" xsi:type="ref:manualService" xmlns:ref="ServiceRef"/>
            </tra:route>.convert

  val route =  xml \ "route"
  Console println route.unselect
}

Output:

  <tra:route>
  <spo:id xmlnls:spo="sport">23232322</spo:id>
  <tra:service xsi:type="ref:manualService" ref="go"/>
  </tra:route>

So, the input xml and the output are not the same. Why?


Source: (StackOverflow)

Advertisements

Zipping zippers in Anti-XML

In this question, the asker wants to transform documents like this:

<text>
  The capitals of Bolivia are <blank/> and <blank/>.
</text>

Into this:

<text>
  The capitals of Bolivia are <input name="blank.1"> and <input name="blank.2">.
</text>

As I noted in my answer there, Anti-XML's zippers provide a clean solution to this problem. The following, for example, would work for renaming the blank elements:

import com.codecommit.antixml._

val q = <text>The capitals of Bolivia are <blank/> and <blank/>.</text>.convert

(q \\ "blank").map(_.copy(name = "input")).unselect

Unfortunately the following doesn't work:

(q \\ "blank").zipWithIndex.map { case (el, i) => el.copy(
  name = "input",
  attrs = Attributes("name" -> "blank.%d".format(i + 1))
)}.unselect

Because of course once we've zipWithIndex-ed the zipper we no longer have a zipper, just an IndexedSeq—we can't have a Zipper[(Node, Int)] because the definition is trait Zipper[+A <: Node] ....

Is there a clean way to use zip or zipWithIndex on an Anti-XML zipper, do some other operations with map, etc., and end up with something that's still a zipper?


Source: (StackOverflow)

Scala XML Library for 2.10+

I've been surprised by how non-intuitive the standard Scala XML library is (beyond defining in-line XML and basic path tree traversal) as well as the lack of any apparent replacements. It looks like at one point anti-xml was gaining traction but it appears that development has been stale for some time.

Specifically I'm looking to manipulate the XML tree by adding and removing sub-trees, something along the lines of:

val tree1 = <root><foo>foo</foo></root>
val tree2 = <root><bar>bar</bar></root>
tree1 + tree2 == <root><foo>foo</foo><bar>bar</bar></root>

Pimping the existing Scala XML library is certainly an option but if there are existing libraries that afford this functionality I'd prefer to let them do the heavy lifting.

Do folks have recommendations on appropriate XML libraries for Scala in 2015 (i.e. >= 2.10) where this sort of manipulation is possible and straightforward?


Source: (StackOverflow)

Anti-XML Group "collect" is not collecting

I am cross-posting this from scala-user:

I have the following:

object XmlTest {

  import com.codecommit.antixml._

  implicit def toPicker(nodes: Group[Node]): Picker = new Picker(nodes)

  class Picker(nodes: Group[Node]) {
    def pick[A <: Node : ClassManifest]: Group[A] = nodes collect {
      case a if implicitly[ClassManifest[A]].erasure.isInstance(a) => a.asInstanceOf[A]
    }
  }

  def testCollect(elems: Group[Elem]) {
    println("size before collect = " + elems.size)
    val es = elems collect {
      case e if e.name == "c" => println("element name is " + e.name); e
    }
    println("size after collect = " + es.size)
  }

  def main(args: Array[String]) {
    val xml = XML.fromString("<a><b/><c/><d/></a>")

    // this works because <a> has only elements as children
    testCollect(xml.children.asInstanceOf[Group[Elem]])

    // pick filters collection by type
    testCollect(xml.children.pick[Elem])
  }
}

When i ran it, it printed the following:

[info] size before collect = 3           // size is 3
[info] element name is c                 // element c matches
[info] size after collect = 1              // this is correct
[info] size before collect = 3           // size is the same as the previous case
[info] element name is c                 // element "c" is matched as well
[info] size after collect = 0               // this should be 1

I am at a lost here. What is going on?


Source: (StackOverflow)

Append element as child of Anti-XML element

Suppose I have an XML document stored as an Anti-XML Elem:

val root : Elem =
    <foo attr="val">
        <bar/>
    </foo>

. I want to append <baz>blahblahblah</baz> to the root element as a child, giving

val modified_root : Elem =
    <foo attr="val">
        <bar/>
        <baz>blahblahblah</baz>
    </foo>

For comparison, in Python you can just root.append(foo).

I know I can append (as a sibling) to a Group[Node] using :+, but that's not what I want:

<foo attr="val">
    <bar/>
</foo>
<baz>blahblahblah</baz>

How do I append it as the last child of <foo>? Looking at the documentation I see no obvious way.


Similar to Scala XML Building: Adding children to existing Nodes, except this question is for Anti-XML rather than scala.xml.


Source: (StackOverflow)

Replacing an XML node with Anti-XML

I am struggling to replace a XML element with another one using the library anti-xml. For instance, I have:

<root>
  <sub>
    <keep />
    <replace />
    <keeptoo />
  </sub>
</root>

and the fragment:

<inserted key="value">
  <foo>foo</foo>
  <bar>bar</bar>
</inserted>

I would like to produce:

<root>
  <sub>
    <keep />
    <inserted key="value">
      <foo>foo</foo>
      <bar>bar</bar>
    </inserted>      
    <keeptoo />
  </sub>
</root>

Note: The order of <sub> children must be conserved.


Source: (StackOverflow)

Best way to remove an element in an XML using anti-xml

What would be the best and/or simplest way to remove an element from a XML document using anti-xml?


Source: (StackOverflow)

Can you use antixml to create xml documents?

there are a few examples for using Anti-Xml to extract information from XML documents, but none that I could find of using Anti-Xml to create XML documents. Does Anti-Xml support creating documents, or should I use another library for this (which one?). Does anyone have an example of creating an XML document with Anti-Xml?


Source: (StackOverflow)

An example of xml processing but using anti-xml instead of Scala xml

I'd like to see a rewrite of bellow script using http://anti-xml.org instead of Scala XML.

This is an excerpt from Chapter 10. Herding XML in Scala - http://ofps.oreilly.com/titles/9780596155957/HerdingXMLInScalaDSLs.html

// code-examples/XML/reading/pattern-matching-script.scala
import scala.xml._
val someXML =
 <sammich>
   <bread>wheat</bread>
   <meat>salami</meat>
   <condiments>
     <condiment expired="true">mayo</condiment>
     <condiment expired="false">mustard</condiment>
   </condiments>
</sammich>

someXML match {
 case <sammich>{ingredients @ _*}</sammich> => {
    for (cond @ <condiments>{_*}</condiments> <- ingredients)
      println("condiments: " + cond.text)
    }
}

Thanks


Source: (StackOverflow)

Anti-XML: Some modifications on Zipper with custom Selectors don't persist after unselect

To test a method that would transform Text elements in an XML document I wrote two very simple Selectors and applied map/toUpperCase on the resulting Zipper. The result should be that all text elements except those excluded via the first Selector are transformed to upper case. But it only works for furthest-down Text elements. Here's the code:

scala> import com.codecommit.antixml._
import com.codecommit.antixml._

scala> val elemSelector = Selector({case x:Elem if x.name != "note" => x})
elemSelector: com.codecommit.antixml.Selector[com.codecommit.antixml.Elem] = <function1>

scala> val textSelector = Selector({case x:Text => x})
textSelector: com.codecommit.antixml.Selector[com.codecommit.antixml.Text] = <function1>

scala> val xml = XML.fromString("<tei><div><p>this<note>not<foreign lang=\"greek\">that</foreign>not</note></p><p>those<hi>these</hi></p></div></tei>")
xml: com.codecommit.antixml.Elem = <tei><div><p>this<note>not<foreign lang="greek">that</foreign>not</note></p><p>those<hi>these</hi></p></div></tei>

scala> val zipper = xml \\ elemSelector \ textSelector
zipper: com.codecommit.antixml.Zipper[com.codecommit.antixml.Text] = thisthatthosethese

scala> val modified = zipper.map(t => new Text(t.text.toUpperCase))
modified: com.codecommit.antixml.Zipper[com.codecommit.antixml.Text] = THISTHATTHOSETHESE

scala> val result = modified.unselect.unselect
result: com.codecommit.antixml.Zipper[com.codecommit.antixml.Node] = <tei><div><p>this<note>not<foreign lang="greek">THAT</foreign>not</note></p><p>those<hi>THESE</hi></p></div></tei>

So, in the second to last command, the upper case is applied to all targeted Text elements, but after stepping out of the zipper, only two of the four elements are transformed. I've tried it with <hi/> instead of <hi>these</hi> and then those gets capitalized. Any idea what's the problem here?

I am using the arktekk.no fork for Scala 2.10.3.


Source: (StackOverflow)