diff --git a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/matchir/MatchIr.scala b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/matchir/MatchIr.scala
index cfea2be2..91be782b 100644
--- a/scalapact-shared/src/main/scala/com/itv/scalapact/shared/matchir/MatchIr.scala
+++ b/scalapact-shared/src/main/scala/com/itv/scalapact/shared/matchir/MatchIr.scala
@@ -8,10 +8,15 @@ import com.itv.scalapact.shared.utils.Helpers.{
safeStringToDouble
}
+import javax.xml.parsers.SAXParserFactory
import scala.util.Try
-import scala.xml.{Elem, Node, XML}
+import scala.xml.factory.XMLLoader
+import scala.xml.{Elem, Node}
object MatchIr {
+
+ private val XML: XMLLoader[Elem] = createXMLParser()
+
def fromXmlString(xmlString: String): Option[IrNode] =
Try(XML.loadString(xmlString)).toOption.map(fromXml)
@@ -21,6 +26,13 @@ object MatchIr {
def fromJSON(fromJson: String => Option[IrNode])(jsonString: String): Option[IrNode] =
fromJson(jsonString)
+ private def createXMLParser(): XMLLoader[Elem] = {
+ val sAXParserFactory = SAXParserFactory.newInstance()
+ sAXParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
+ val saxParser = sAXParserFactory.newSAXParser()
+ xml.XML.withSAXParser(saxParser)
+ }
+
private def convertAttributes(attributes: Map[String, String], pathToParent: IrNodePath): IrNodeAttributes =
attributes.toList.reverse
.map {
diff --git a/tests-with-deps/src/test/scala/com/itv/scalapact/shared/matchir/MatchIrSpec.scala b/tests-with-deps/src/test/scala/com/itv/scalapact/shared/matchir/MatchIrSpec.scala
index c42a0dd2..cbe4a703 100644
--- a/tests-with-deps/src/test/scala/com/itv/scalapact/shared/matchir/MatchIrSpec.scala
+++ b/tests-with-deps/src/test/scala/com/itv/scalapact/shared/matchir/MatchIrSpec.scala
@@ -97,6 +97,28 @@ class MatchIrSpec extends AnyFunSpec with Matchers {
}
+ it("should be able to convert xml with a document type definition") {
+ val xml: String =
+ """]>""".stripMargin
+
+ val ir: IrNode =
+ IrNode(
+ "animals",
+ IrNode("alligator")
+ .withAttributes(
+ IrNodeAttributes(
+ Map(
+ "name" -> IrNodeAttribute(IrStringNode("Mary"), IrNodePathEmpty <~ "animals" <~ "alligator" <@ "name")
+ )
+ )
+ )
+ .withPath(IrNodePathEmpty <~ "animals" <~ "alligator")
+ .markAsXml
+ ).withPath(IrNodePathEmpty <~ "animals").markAsXml
+
+ check(MatchIr.fromXmlString(xml).get =<>= ir)
+ }
+
it("should be able to convert one node with content") {
val xml: String = haddock.toString()