Hi, addition of a new flag withRemoveNamespaces ( issue https://github.com/valentiay/phobos/issues/3 , pr https://github.com/valentiay/phobos/pull/5 ) is a really useful thing, but there is one bug, this config does not work with attributes if namespace is set. Here is an example with a comparison of this flag for an "element" and for "attribute". (it works correctly for "element", it doesn't work for "attribute").
import phobos.Namespace
import phobos.configured.ElementCodecConfig
import phobos.decoding.XmlDecoder
import phobos.derivation.semiauto.{deriveXmlDecoderConfigured, deriveXmlEncoderConfigured}
import phobos.encoding.XmlEncoder
import phobos.syntax.attr
object MyNamespace {
type ns = MyNamespace.type
implicit val ns: Namespace[ns] = Namespace.mkInstance[ns]("http://example.com", Some("example"))
}
case class BarAttr(@attr foo: String)
object BarAttr {
val configEnc: ElementCodecConfig = ElementCodecConfig.default.withAttributesDefaultNamespace(MyNamespace)
val configDec: ElementCodecConfig = ElementCodecConfig.default.withRemoveNamespaces
implicit val barXmlEncoder: XmlEncoder[BarAttr] =
deriveXmlEncoderConfigured[BarAttr]("BarAttr", configEnc)
implicit val barXmlDecoder: XmlDecoder[BarAttr] =
deriveXmlDecoderConfigured[BarAttr]("BarAttr", configDec)
}
case class BarElem(foo: String)
object BarElem {
val configEnc: ElementCodecConfig = ElementCodecConfig.default.withElementsDefaultNamespace(MyNamespace)
val configDec: ElementCodecConfig = ElementCodecConfig.default.withRemoveNamespaces
implicit val barXmlEncoder: XmlEncoder[BarElem] =
deriveXmlEncoderConfigured[BarElem]("BarElem", configEnc)
implicit val barXmlDecoder: XmlDecoder[BarElem] =
deriveXmlDecoderConfigured[BarElem]("BarElem", configDec)
}
object App {
def main(args: Array[String]): Unit = {
println(XmlEncoder[BarAttr].encode(BarAttr("qwerty")))
// <?xml version='1.0' encoding='UTF-8'?><BarAttr xmlns:ans1="http://example.com" ans1:foo="qwerty"/>
println(XmlEncoder[BarElem].encode(BarElem("qwerty")))
// <?xml version='1.0' encoding='UTF-8'?><BarElem><ans1:foo xmlns:ans1="http://example.com">qwerty</ans1:foo></BarElem>
val xmlAttr =
"""<?xml version='1.0' encoding='UTF-8'?><BarAttr xmlns:ans1="http://example.com" ans1:foo="qwerty"/>"""
println(XmlDecoder[BarAttr].decode(xmlAttr))
// {{{
// phobos.decoding.DecodingError: Error while decoding XML: Missing 'foo' attribute
// In element 'BarAttr'
// }}}
val xmlElem =
"""<?xml version='1.0' encoding='UTF-8'?><BarElem><ans1:foo xmlns:ans1="http://example.com">qwerty</ans1:foo></BarElem>"""
println(XmlDecoder[BarElem].decode(xmlElem))
// Ok
// Check law for element
val y: BarElem = BarElem("qwerty")
assert(
XmlEncoder[BarElem]
.encode(y)
.toOption
.flatMap(XmlDecoder[BarElem].decode(_).toOption)
.contains(y),
) // Ok
// Check law for attribute
val x: BarAttr = BarAttr("qwerty")
assert(
XmlEncoder[BarAttr]
.encode(x)
.toOption
.flatMap(XmlDecoder[BarAttr].decode(_).toOption)
.contains(x),
) // assertion failed
}
}
Hi!
Thank you for reporting this issue.
This is a tricky one. I'll need some more time to investigate why does it work that way. I'm surprised, that it does not break the law for elements
Hi, addition of a new flag
withRemoveNamespaces
( issue https://github.com/valentiay/phobos/issues/3 , pr https://github.com/valentiay/phobos/pull/5 ) is a really useful thing, but there is one bug, this config does not work with attributes if namespace is set. Here is an example with a comparison of this flag for an "element" and for "attribute". (it works correctly for "element", it doesn't work for "attribute").