
scales.xml.equals.XmlEquals.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scales-xml_2.11 Show documentation
Show all versions of scales-xml_2.11 Show documentation
An alternate Scala Xml processing library
The newest version!
package scales.xml.equals
import scales.xml.{PullType, QName, Elem, Attribs, Attributes, Attribute, XmlItem, XmlPath, EndElem, XCC, Misc, Miscs}
import scales.xml.serializers.NamespaceContext
import scala.collection.immutable.Map
import scalaz._
import Scalaz._
object BasicPaths {
// {ns}Local -> count
type BasicPathA = (QName, Map[String, Int])
type BasicPath = List[BasicPathA]
}
import BasicPaths._
/**
* Base functions for equality
*/
trait XmlEquals {
/**
* Allows comparison of Text nodes or Attribute values that contain QNames, i.e. prefix:value. In order to perform this comparison both the left and right sides must have a NamespaceContext.
*/
def qnamesEqual(context : ComparisonContext, str : String, str2 : String) = {
// split both, if one has and the other not, then its false anyway
val sp1 = str.split(":")
val sp2 = str2.split(":")
if (sp1.size == 2 && sp2.size == 2) {
sp1(1) == sp2(1) && { // values match
// look up prefixes
(for{ lnc <- context.leftNamespaceContext
rnc <- context.rightNamespaceContext
lns <- lnc.mappings.get(sp1(0))
rns <- rnc.mappings.get(sp2(0))
} yield lns == rns
).
getOrElse(false)
}
} else
str == str2
}
/**
* Perform an actual token comparison (Text/CData and Attribute value relevant).
*/
def compareTokens( context : ComparisonContext, qnameTokenComparison : Option[(ComparisonContext, String, String) => Boolean], str : String, str2 : String) =
qnameTokenComparison.
map( f =>
f(context, str, str2)
).
getOrElse(str == str2)
/**
* Compare the xml object via the available XmlDifference type class
*/
def compare[T : XmlComparison]( left : T, right : T) : Option[(XmlDifference[_], ComparisonContext)] =
implicitly[XmlComparison[T]].compare(true, ComparisonContext(), left, right)
/**
* Compare the xml object via the available XmlDifference type class
*/
def compare[T : XmlComparison]( context : ComparisonContext, left : T, right : T) : Option[(XmlDifference[_], ComparisonContext)] =
implicitly[XmlComparison[T]].compare(true, context, left, right)
}
/**
* Make it available without dragging the rest of the world in
*/
object XmlEquals extends XmlEquals {
}
import XmlEquals._
/**
* All default exact Xml Equal and XmlComparison trait instances.
*
* CData, Comments, PI are all kept as is, DTD, encoding and prolog etc are not. Text nodes are not joined. Use LogicalXmlEquals to focus more on content only.
*/
trait ExactXmlEquals
extends DefaultItemEquals
with DefaultAttributeEquals
with DefaultAttributesEquals
with DefaultElemEquals
with ExactStreamEquals
with QNameEquals
with DefaultQNameToken {
}
/**
* Provides simple access to ExactXmlEquals
*/
object ExactXmlEquals extends ExactXmlEquals {}
/**
* All CData nodes are converted to text nodes, adjoining Text nodes (including CData) are joined.
*/
trait DefaultXmlEquals
extends DefaultItemEquals
with DefaultAttributeEquals
with DefaultAttributesEquals
with DefaultElemEquals
with DefaultStreamEquals
with QNameEquals
with DefaultQNameToken
with DefaultDocLikeEquals {
}
object DefaultXmlEquals extends DefaultXmlEquals {}
import scales.utils.collection.{path => upath}
/**
* Makes the given path the top path
*/
class PathAsPullTypeIterable( originalPath : XmlPath ) extends upath.AbstractPathIterator[XmlItem, Elem, XCC, PullType] {
def initialPath : XmlPath = originalPath.copy( top = upath.Top() )
def event : PullType = path.node.focus.fold(x=>x,y=>y.section)
def end = {
val el = path.tree.section
EndElem(el.name, el.namespaces) : PullType
}
}
/**
* For Iterator[PullType]s that actually are, lets help the inference and implicit lookup out
*/
trait TheyReallyAreIterators {
import scales.xml.{CloseablePull, XmlPull}
implicit val closeablePullIsAn = (x : CloseablePull) => x : Iterator[PullType]
implicit val xmlPullIsAn = (x : XmlPull) => x : Iterator[PullType]
}
/**
* Collection of all implicit conversions to StreamComparables.
*
* NOTE: The results are only usable with compare / ===, and should not be used to serialize
*/
trait StreamComparableImplicits extends TheyReallyAreIterators {
import scales.xml.{CloseablePull, XmlPull, DocLike, Doc, XmlTree}
implicit val itrPlusDocAsAnIterator = (x : (Iterator[PullType], DocLike)) => x._1 : Iterator[PullType]
/**
* Converts directly to a StreamComparable, its not generally a good idea to automagically mix XmlPath as an Iterable with XmlPath as an Iterator, make it explicit if thats really desired.
*/
implicit val xmlPathToComparable : XmlPath => StreamComparable[XmlPath] = ( x : XmlPath ) => new StreamComparable[XmlPath](x)(t => new PathAsPullTypeIterable(t))
/**
* Converts XmlTree and DslBuilder (when used with PullTypeConversionImplicits
*/
implicit def fromStreamToStreamComparable[T <% Iterator[PullType]](t : T) : StreamComparable[T] =
new StreamComparable(t)
/**
* One off for (Iterator, DocLike)
*/
implicit def itrDocLikeToStreamComparable[T <% Iterator[PullType]](t : (T, DocLike)) : StreamComparable[T] = new StreamComparable( t._1 )
/**
* Wrapper for Docs
*/
implicit def docWrapper(implicit bodyComp : XmlComparison[XmlTree]) : DocLikeWrapper[Doc] = new DocLikeWrapperBase[Doc, XmlTree]( identity, _.rootElem, bodyComp )
/**
* Wrapper for XmlPull
*/
implicit def xmlPullWrapper(implicit bodyComp : XmlComparison[Iterator[PullType]]) : DocLikeWrapper[XmlPull] = new DocLikeWrapperBase[XmlPull, Iterator[PullType]]( identity, identity, bodyComp )
/**
* Wrapper for CloseablePull
*/
implicit def closeablePullWrapper(implicit bodyComp : XmlComparison[Iterator[PullType]]) : DocLikeWrapper[CloseablePull] = new DocLikeWrapperBase[CloseablePull, Iterator[PullType]]( identity, identity, bodyComp )
/**
* Wrapper for (Iterator, DocLike)
*/
implicit def itrDocLikeWrapper(implicit bodyComp : XmlComparison[Iterator[PullType]]) : DocLikeWrapper[(Iterator[PullType], DocLike)] = new DocLikeWrapperBase[(Iterator[PullType], DocLike), Iterator[PullType]]( _._2, _._1, bodyComp )
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy