使用xerces java的最新版本发现xml文档的schema无法指定相对路径!xml文档、schema和程序如下。如果将schema放到当前目录之下,则顺利通过;
如果将schema与xml文档放在相同目录之下,即指望xerces能在xml文档的目录中找到schema,竟失败!如果将程序中的parser.parse(inputSource);直接改成parser.parse("E:/projects/java/rms/templates/o.xml");
则是可以的,因为这里的参数将被按照URI进行处理,然后就能找到相对目录下的schema,但这样的话,由于URI处理中文有问题,文件名就不能采用中文了。
xml文档如下:
<?xml version="1.0" encoding="gb2312"?>
<ResourceReg xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNameSpaceSchemaLocation="registration.xsd">
  <ResourceFig>
    <ResourceKID>512</ResourceKID>
    <PortAddr>192.192.192.222:1:1</PortAddr>
    <ResourceSID>3</ResourceSID>
  </ResourceFig>
  <ResourceStatus>
    <ZBWZ>135,26</ZBWZ>
    <YXZT>1</YXZT>
    <CSQB>true</CSQB>
    <BKF>2</BKF>
  </ResourceStatus>
</ResourceReg>schema如下:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="ResourceReg">
  <xs:complexType>
   <xs:all>
    <xs:element name="ResourceFig" type="ResourceFig" minOccurs="1" maxOccurs="1" />
    <xs:element name="ResourceStatus" minOccurs="1" maxOccurs="1" />
   </xs:all>
  </xs:complexType>
 </xs:element>
 <xs:complexType name="ResourceFig">
  <xs:all>
   <xs:element name="ResourceKID" type="xs:unsignedShort" />
   <xs:element name="PortAddr" type="xs:token" />
   <xs:element name="ResourceSID" type="xs:unsignedByte" />
  </xs:all>
 </xs:complexType>
</xs:schema>程序如下:
    DOMParser parser = new DOMParser();
    Document doc = null;
    try
    {
      parser.setFeature("http://xml.org/sax/features/validation",true);
      parser.setFeature("http://apache.org/xml/features/validation/schema",true);
      InputSource inputSource=new InputSource(
          new FileInputStream(
          new File("E:/projects/java/rms/templates/o.xml")));
      parser.parse(inputSource);
      doc = parser.getDocument();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }

解决方案 »

  1.   

    用System.getProperty("user.dir")+工用目录
      

  2.   

    I have found a solution to this problem. I think xcerces should support GB2312 encoding (Chinese). 
    The solution also solves another problem that xceces does not support files encoded in GB2312. 
    The solution is as below: in org.apache.xerces.impl.XMLEntityManager.createReader(InputStream,String,Boolean) add: 
    /** 
    * why not supporting GB2312? 
    * @author [email protected] 
    */ 
    if(encoding.equals("GB2312")) 

    return new InputStreamReader(inputStream,encoding); 
    } and in org.apache.xerces.util.URI.initializePath(String, int) update: 
                    else if (!isPathCharacter(testChar)) 
                    { 
                      /** 
                       * @author [email protected] 
                       * The path part of a URI may contain characters which are not included in URI Spec. 
                       */ 
                      if(Character.isUnicodeIdentifierStart(testChar)||Character.isUnicodeIdentifierPart(testChar)) 
                      { 
                        ++index; 
                        continue; 
                      }                   if (testChar == '?' || testChar == '#') 
                      { 
                        break; 
                      } 
                      throw new MalformedURIException("Path contains invalid character: " + testChar); 
                    } and in org.apache.xerces.util.URI.initializePath(String, int) update: 
                    else if (!isURICharacter(testChar)) 
                    { 
                      /** 
                       * A path may contain Chinese characters, 
                       * but I am not sure that the method used here is right. 
                       * And I believe that there must be other parts of this file to be corrected. 
                       * And why not use java.net.URI? 
                       * By [email protected] 
                       */ 
                      if(Character.isUnicodeIdentifierPart(testChar)||Character.isUnicodeIdentifierStart(testChar)) 
                      { 
                        index++; 
                        continue; 
                      } 
                        throw new MalformedURIException( 
                            "Opaque part contains invalid character: " + testChar); 
                    }