Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

org.xml.sax.SAXParseException: The entity "reg" was referenced, but not declared. #9

Closed
asifmom opened this issue Nov 17, 2016 · 7 comments

Comments

@asifmom
Copy link

asifmom commented Nov 17, 2016

For the following xml node,

<REGISTEREDNAME indication="something" country="European Union" company="abcd">cde&reg;</REGISTEREDNAME>

Following exception is thrown :
org.xml.sax.SAXParseException: The entity "reg" was referenced, but not declared.

How do I disable entity validation in xmlunit. In my case, I cannot modify the xml.

@bodewig
Copy link
Member

bodewig commented Nov 17, 2016

Assuming you are talking about detecting differences, you can configure the DocumentBuilderFactory used by DOMDifferenceEngine and DiffBuilder explicitly, see http://www.xmlunit.org/api/java/2.3.0/org/xmlunit/builder/DiffBuilder.html#withDocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) .

Is it enough to set it to be non.validating - http://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setValidating(boolean) ?

@asifmom
Copy link
Author

asifmom commented Nov 18, 2016

Following two versions of the code are throwing the same exception. I have tried with 2.2.1 and 2.30 versions

 val dbf = DocumentBuilderFactory.newInstance()
 dbf.setValidating(false)
 Diff d = DiffBuilder.compare(Input.fromString(...)).withTest(
     Input.fromString(...)).withDocumentBuilderFactory(dbf)
          .ignoreWhitespace().build();

and

    val documentBuilderFactory = DocumentBuilderFactory.newInstance()
    documentBuilderFactory.setValidating(false)
    val control= Convert.toDocument(Input.fromString(actualOutput).build,documentBuilderFactory)

@bodewig
Copy link
Member

bodewig commented Nov 18, 2016

Hmm, I thought setValidating(false) would disable entity validation but it seems I'm wrong. This really is more of an JAXP issue than an XMLUnit problem, we need to figure out how to parse the document into a DOM Document.

http://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setExpandEntityReferences(boolean) looks promising, or you may need to provide an EntityResolver that returns an empty source to a DocumentBuilder and create the Document yourself or something similar.

@asifmom
Copy link
Author

asifmom commented Nov 18, 2016

setExpandEntityReferences doesn't work.

For the time being I have done a horrible hack to make it work. Following is the code.
val diff = DiffBuilder .compare(XmlEntityReplacer.derefenceEntities(actualOutput)) .withTest(XmlEntityReplacer.derefenceEntities(expectedOutput))

the code for XmlEntityReplacer

object XmlEntityReplacer {

  val entityMap = Map(
    "&reg;" -> "&#174;",
    "&nbsp;" -> "&#160;",
    "&micro;" -> "&#181;",
    "&frac12;" -> "&#189;",
    "&alpha;" -> "&#913;",
    "&ge;" -> "&#8805;",
    "&le;" -> "&#8804;",
    "&minus;" -> "&#8722;",
    "&infin;" -> "&#8734;",
    "&lsquo;" -> "&#8216;",
    "&middot;" -> "&#183;"
  )

  def derefenceEntities(xmlString: String)={
    entityMap.foldLeft(xmlString){(changedXmlString,key)=>changedXmlString.replace(key._1,key._2)}
  }

}


@bodewig
Copy link
Member

bodewig commented Dec 4, 2016

If there is no DTD that defines the entities then your documents are not well-formed XML documents, strictly speaking. If you cannot change the document to reference the DTD (HTML, likely) I'm afraid your hack is the only way to go.

An equally ugly alternative would be to inject an internal DTD block that defined the entities by doing something similar to https://github.com/xmlunit/xmlunit/blob/master/xmlunit-legacy/src/main/java/org/custommonkey/xmlunit/DoctypeInputStream.java which inserts a DOCTYPE declaration into the stream (or replaces an existing one).

BTW, &gt; and&lt; are standard XML entities you don't need to replace yourself.

Do you think there is anything XMLUnit could be doing to help in your case?

@asifmom
Copy link
Author

asifmom commented Dec 5, 2016

I guess, the only thing xmlunit can do is to provide an option to inject external DTDs before the validation.

@bodewig
Copy link
Member

bodewig commented Dec 6, 2016

I've created xmlunit/xmlunit#90 for this as it may get more visibility over there, closer to the code.

Please take a look at the issue and yell in case I've forgotten anything.

Thanks.

@bodewig bodewig closed this as completed Dec 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants