Xerces2-J
  1. Xerces2-J
  2. XERCESJ-1537

Problem with unparsed entity location when indirect referenced in the DTDs

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.9.1
    • Fix Version/s: None
    • Component/s: DTD
    • Labels:
      None
    • Environment:
      All

      Description

      We have an XML file with the content:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE doc SYSTEM "../dtd/entityProblem.dtd">
      <doc>
      <fig image="test"/>
      </doc>

      The main DTD "entityProblem.dtd" (located in the right folder) has the following content:

      <!ELEMENT doc ( fig )>
      <!ELEMENT fig EMPTY>
      <!ATTLIST fig image ENTITY #REQUIRED>

      <!ENTITY % entityProblem SYSTEM "../source/entityProblem.ent">
      %entityProblem;

      and the included DTD "entityProblem.ent" which is included in a relative folder has the content:

      <?xml version="1.0" encoding="UTF-8"?>
      <!NOTATION gif SYSTEM "gif">
      <!ENTITY % test '<!ENTITY test SYSTEM "images/crane.gif" NDATA gif>'>
      %test;

      If we transform the XML with an XSLT processor which uses Xerces for parsing (like Saxon) with the content like:

      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
      <xsl:template match="/">
      <xsl:text>
      </xsl:text>
      <xsl:value-of select="unparsed-entity-uri(/doc/fig/@image)"/>
      <xsl:text>
      </xsl:text>
      </xsl:template>
      </xsl:stylesheet>

      Then the unparsed entity location will be resolved relative to the current file directory (new File(".")) instead of resolving it relative to the DTD where it was declared.

      A possible solution is to make modifications in the org.apache.xerces.impl.XMLEntityManager on the "org.apache.xerces.impl.XMLEntityManager.startEntity(String, boolean)" method and in the case of InternalEntity, instead of creating for it an XMLInputSource like:

      xmlInputSource = new XMLInputSource(null, null, null, reader, null);

      you could set a system ID to the input source like:

      xmlInputSource = new XMLInputSource(null, fCurrentEntity != null ? fCurrentEntity.getExpandedSystemId() : null, null, reader, null);

      We implemented this solution in Oxygen XML Editor as a patch but there are still problems, with this solution in place the image system ID is expanded relative to "entityProblem.dtd" and not relative to "entityProblem.ent".
      Using MSXML.NET the image location is correctly solved relative to "entityProblem.ent"

        Activity

        Hide
        Octavian Nadolu added a comment -

        I found a better fix for the XMLEntityManager, that is implemented in Oxygen XML Editor as a patch for a while. We have also some test for this case and seems to work fine. You need to set a system id of the current entity (fCurrentEntity), in the current entity reference. To obtain the current entity system id you have to use fCurrentEntity.entityLocation.getExpandedSystemId().

        In the "startEntity(String, boolean)" method and in the case of InternalEntity, instead of creating for it an XMLInputSource like:

        xmlInputSource = new XMLInputSource(null, null, null, reader, null);

        you could set a system ID to the input source like:

        xmlInputSource = new XMLInputSource(
        null,
        fCurrentEntity != null && fCurrentEntity.entityLocation != null) ? fCurrentEntity.entityLocation.getExpandedSystemId() : null,
        null,
        reader,
        null);

        Show
        Octavian Nadolu added a comment - I found a better fix for the XMLEntityManager, that is implemented in Oxygen XML Editor as a patch for a while. We have also some test for this case and seems to work fine. You need to set a system id of the current entity (fCurrentEntity), in the current entity reference. To obtain the current entity system id you have to use fCurrentEntity.entityLocation.getExpandedSystemId(). In the "startEntity(String, boolean)" method and in the case of InternalEntity, instead of creating for it an XMLInputSource like: xmlInputSource = new XMLInputSource(null, null, null, reader, null); you could set a system ID to the input source like: xmlInputSource = new XMLInputSource( null, fCurrentEntity != null && fCurrentEntity.entityLocation != null) ? fCurrentEntity.entityLocation.getExpandedSystemId() : null, null, reader, null);
        Michael Glavassevich made changes -
        Assignee Michael Glavassevich [ mrglavas@ca.ibm.com ]
        Radu Coravu made changes -
        Field Original Value New Value
        Attachment uri-problem.zip [ 12495339 ]
        Hide
        Radu Coravu added a comment -

        The samples necessary to reproduce the problem.

        Show
        Radu Coravu added a comment - The samples necessary to reproduce the problem.
        Radu Coravu created issue -

          People

          • Assignee:
            Michael Glavassevich
            Reporter:
            Radu Coravu
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:

              Time Tracking

              Estimated:
              Original Estimate - 4h
              4h
              Remaining:
              Remaining Estimate - 4h
              4h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development