<any> and <anyAttribute>
Last time I wrote:
Next goal is to handle
<any>
without ignoring it completely using this generic container. I can probably store thescala.xml.Elem
object "as is" in a collection. The user of round trip probably would expect that I don't lose luggage during the flight.
That's pretty much what I did for two usages of <any>
handled by scalaxb. First pattern is that it could appear as part of the sequence.
<element name="Choice1">
<complexType>
<sequence>
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
scalaxb generates the following:
case class Choice1(any: org.scalaxb.rt.DataRecord[scala.xml.Node]*) extends org.scalaxb.rt.DataModel { def toXML(namespace: String, elementLabel: String, scope: scala.xml.NamespaceBinding): scala.xml.Node = { val prefix = scope.getPrefix(namespace) var attribute: scala.xml.MetaData = scala.xml.Null scala.xml.Elem(prefix, elementLabel, attribute, scope, Seq(any.map(x => x.toXML(x.namespace, x.key, scope))).flatten: _*) } } object Choice1 { def fromXML(node: scala.xml.Node): Choice1 = Choice1((node.child.partialMap { case x: scala.xml.Elem => org.scalaxb.rt.DataRecord(x.scope.getURI(x.prefix), x.label, x) }).toList: _*) }
The second is that it could appear as part of choice particle.
<element name="Element1">
<complexType>
<sequence>
<choice maxOccurs="unbounded">
<element ref="ipo:Choice1"/>
<any namespace="##other" processContents="lax" />
</choice>
</sequence>
</complexType>
</element>
scalaxb generates the following:
case class Element1(arg1: org.scalaxb.rt.DataRecord[Any]*) extends org.scalaxb.rt.DataModel { def toXML(namespace: String, elementLabel: String, scope: scala.xml.NamespaceBinding): scala.xml.Node = { val prefix = scope.getPrefix(namespace) var attribute: scala.xml.MetaData = scala.xml.Null scala.xml.Elem(prefix, elementLabel, attribute, scope, Seq(arg1.map(x => x.toXML(x.namespace, x.key, scope))).flatten: _*) } } object Element1 { def fromXML(node: scala.xml.Node): Element1 = Element1(node.child.filter(Element1Option.fromXML.isDefinedAt(_)).map(x => Element1Option.fromXML(x)).toList: _*) } trait Element1Option extends org.scalaxb.rt.DataModel object Element1Option { def fromXML: PartialFunction[scala.xml.NodeSeq, org.scalaxb.rt.DataRecord[Any]] = { case x: scala.xml.Elem if (x.label == "Choice1" && x.scope.getURI(x.prefix) == "http://www.example.com/IPO") => org.scalaxb.rt.DataRecord(x.scope.getURI(x.prefix), x.label, Choice1.fromXML(x)) case x: scala.xml.Elem => org.scalaxb.rt.DataRecord(x.scope.getURI(x.prefix), x.label, x) } }
Finally, scalaxb now supports <anyAttribute>
:
<element name="Element2">
<complexType>
<anyAttribute namespace="##any"/>
</complexType>
</element>
scalaxb generates the following:
case class Element2(anyAttribute: Seq[org.scalaxb.rt.DataRecord[String]]) extends org.scalaxb.rt.DataModel { def toXML(namespace: String, elementLabel: String, scope: scala.xml.NamespaceBinding): scala.xml.Node = { val prefix = scope.getPrefix(namespace) var attribute: scala.xml.MetaData = scala.xml.Null anyAttribute.foreach(x => if (x.namespace == null) attribute = scala.xml.Attribute(null, x.key, x.value, attribute) else attribute = scala.xml.Attribute(scope.getPrefix(x.namespace), x.key, x.value, attribute)) scala.xml.Elem(prefix, elementLabel, attribute, scope, Seq().flatten: _*) } } object Element2 { def fromXML(node: scala.xml.Node): Element2 = Element2(node match { case elem: scala.xml.Elem => (elem.attributes.toList) flatMap { case scala.xml.UnprefixedAttribute(key, value, _) => List(org.scalaxb.rt.DataRecord(null, key, value.text)) case scala.xml.PrefixedAttribute(pre, key, value, _) => List(org.scalaxb.rt.DataRecord(elem.scope.getURI(pre), key, value.text)) case _ => Nil } case _ => Nil }) }
It's getting a little messy, but the idea is to keep the data around as DataRecord
so it can persist it back into xml document when the time comes to round trip.