Skip to content

Commit

Permalink
Allow document type definitions to be included when parsing XML for b…
Browse files Browse the repository at this point in the history
…ody matching

Fixes: issue ITV#237
  • Loading branch information
Daniel Beddoe committed Nov 18, 2022
1 parent 211abd3 commit 143fe43
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
"""<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE animals [<!ELEMENT animals (alligator)*><!ELEMENT alligator (#PCDATA)><!ATTLIST alligator name CDATA #REQUIRED>]><animals><alligator name="Mary"/></animals>""".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 = <fish>haddock</fish>.toString()
Expand Down

0 comments on commit 143fe43

Please sign in to comment.