`
fqtrnt
  • 浏览: 9658 次
社区版块
存档分类
最新评论

关于在DOM4J在读取XML文件时,解释DTD的问题

阅读更多

近日在使用 DOM4J 的时候,遇到一个问题,现在有两个解决方法,先记下来,以便日后使用。

问题:对一个 XML 文件进行读写操作,但是发现当文件存在的时候,使用DOM4J读进来的时候,生成的 Document 对象会根据 DTD 里的定义,追加了一些 default 属性(实际不需要)。而且在读取的时间被延长。


有一个 XML 文件如下:<o:p></o:p>

xml 代码
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
  3.   
  4. <beans>   
  5.   ....  
  6. </beans>  

使用 DOM4J 的读取文件的一般性写法:<o:p></o:p>

java 代码
 
  1. SAXReader reader = new SAXReader(false);  
  2. document = reader.read(file);  
  3. root = document.getRootElement();  

对象 document 里的节点会被自动追加 DTD 里的定义的 default 属性,只有新增加的节点不受影响,如下。而且,如果文件的操作时间被延长。

xml 代码
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  
  3.   
  4. <beans default-lazy-init="false" default-autowire="no" default-dependency-check="none">   
  5.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  6.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  7.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  8.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  9.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  10.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  11.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase" lazy-init="default" autowire="default" dependency-check="default"/>    
  12.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase"/>    
  13.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase"/>    
  14.   <bean id="OperateXmlByDom4jTestCase" class="test.OperateXmlByDom4jTestCase"/>  
  15. </beans>  
<o:p></o:p>

为了不让生成我们不需要的 default 属性和缩短文件的操作时间,我们可以调用 SAXReader.setFeature 方法来改变 DOM4J 的行为,片断代码如下:<o:p></o:p>

java 代码
 
  1. // http://apache.org/xml/features/nonvalidating/load-external-dtd"  
  2. saxReader.setFeature(  
  3.     Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE,   
  4.     false);  

关于更多的 Feature 请参考 com.sun.org.apache.xerces.internal.impl.Constants<o:p></o:p>

以下为片断代码:<o:p></o:p>

java 代码
 
  1. // xerces features  
  2.   
  3. /** Xerces features prefix ("http://apache.org/xml/features/"). */  
  4. public static final String XERCES_FEATURE_PREFIX = "http://apache.org/xml/features/";  
  5.   
  6. /** Schema validation feature ("validation/schema"). */  
  7. public static final String SCHEMA_VALIDATION_FEATURE = "validation/schema";  
  8.   
  9. /** Expose schema normalized values */  
  10. public static final String SCHEMA_NORMALIZED_VALUE = "validation/schema/normalized-value";  
  11.   
  12. /** Send schema default value via characters() */  
  13. public static final String SCHEMA_ELEMENT_DEFAULT = "validation/schema/element-default";  
  14.   
  15. /** Schema full constraint checking ("validation/schema-full-checking"). */  
  16. public static final String SCHEMA_FULL_CHECKING = "validation/schema-full-checking";  
  17.   
  18. /** Augment Post-Schema-Validation-Infoset */  
  19. public static final String SCHEMA_AUGMENT_PSVI = "validation/schema/augment-psvi";  
  20.   
  21. /** Dynamic validation feature ("validation/dynamic"). */  
  22. public static final String DYNAMIC_VALIDATION_FEATURE = "validation/dynamic";  
  23.   
  24. /** Warn on duplicate attribute declaration feature ("validation/warn-on-duplicate-attdef"). */  
  25. public static final String WARN_ON_DUPLICATE_ATTDEF_FEATURE = "validation/warn-on-duplicate-attdef";  
  26.   
  27. /** Warn on undeclared element feature ("validation/warn-on-undeclared-elemdef"). */  
  28. public static final String WARN_ON_UNDECLARED_ELEMDEF_FEATURE = "validation/warn-on-undeclared-elemdef";  
  29.   
  30. /** Warn on duplicate entity declaration feature ("warn-on-duplicate-entitydef"). */  
  31. public static final String WARN_ON_DUPLICATE_ENTITYDEF_FEATURE = "warn-on-duplicate-entitydef";  
  32.   
  33. /** Allow Java encoding names feature ("allow-java-encodings"). */  
  34. public static final String ALLOW_JAVA_ENCODINGS_FEATURE = "allow-java-encodings";  
  35.   
  36. /** Disallow DOCTYPE declaration feature ("disallow-doctype-decl"). */  
  37. public static final String DISALLOW_DOCTYPE_DECL_FEATURE = "disallow-doctype-decl";  
  38.   
  39. /** Continue after fatal error feature ("continue-after-fatal-error"). */  
  40. public static final String CONTINUE_AFTER_FATAL_ERROR_FEATURE = "continue-after-fatal-error";  
  41.   
  42. /** Load dtd grammar when nonvalidating feature ("nonvalidating/load-dtd-grammar"). */  
  43. public static final String LOAD_DTD_GRAMMAR_FEATURE = "nonvalidating/load-dtd-grammar";  
  44.   
  45. /** Load external dtd when nonvalidating feature ("nonvalidating/load-external-dtd"). */  
  46. public static final String LOAD_EXTERNAL_DTD_FEATURE = "nonvalidating/load-external-dtd";  
  47.   
  48. /** Defer node expansion feature ("dom/defer-node-expansion"). */  
  49. public static final String DEFER_NODE_EXPANSION_FEATURE = "dom/defer-node-expansion";  
  50.   
  51. /** Create entity reference nodes feature ("dom/create-entity-ref-nodes"). */  
  52. public static final String CREATE_ENTITY_REF_NODES_FEATURE = "dom/create-entity-ref-nodes";  
  53.   
  54. /** Include ignorable whitespace feature ("dom/include-ignorable-whitespace"). */  
  55. public static final String INCLUDE_IGNORABLE_WHITESPACE = "dom/include-ignorable-whitespace";  
  56.   
  57. /** Default attribute values feature ("validation/default-attribute-values"). */  
  58. public static final String DEFAULT_ATTRIBUTE_VALUES_FEATURE = "validation/default-attribute-values";  
  59.   
  60. /** Validate content models feature ("validation/validate-content-models"). */  
  61. public static final String VALIDATE_CONTENT_MODELS_FEATURE = "validation/validate-content-models";  
  62.   
  63. /** Validate datatypes feature ("validation/validate-datatypes"). */  
  64. public static final String VALIDATE_DATATYPES_FEATURE = "validation/validate-datatypes";  
  65.   
  66. /** Notify character references feature (scanner/notify-char-refs"). */  
  67. public static final String NOTIFY_CHAR_REFS_FEATURE = "scanner/notify-char-refs"; 
  68.  
  69. /** Notify built-in (&, etc.) references feature (scanner/notify-builtin-refs"). */  
  70. public static final String NOTIFY_BUILTIN_REFS_FEATURE = "scanner/notify-builtin-refs";  
  71.   
  72. /** Standard URI conformant feature ("standard-uri-conformant"). */  
  73. public static final String STANDARD_URI_CONFORMANT_FEATURE = "standard-uri-conformant";  
  74.   
  75. /** Internal performance related feature:  
  76.  * false - the parser settings (features/properties) have not changed between 2 parses 
  77.  * true - the parser settings have changed between 2 parses   
  78.  * NOTE: this feature should only be set by the parser configuration. 
  79.  */  
  80. public static final String PARSER_SETTINGS = "internal/parser-settings";  
  81.   
  82. /** Feature to make XML Processor XInclude Aware */  
  83. public static final String XINCLUDE_AWARE = "xinclude-aware";  
  84.   
  85. /** Ignore xsi:schemaLocation and xsi:noNamespaceSchemaLocation. */  
  86. public static final String IGNORE_SCHEMA_LOCATION_HINTS = "validation/schema/ignore-schema-location-hints";  
  87.   
  88. /** 
  89.  * When true, the schema processor will change characters events 
  90.  * to ignorableWhitespaces events, when characters are expected to 
  91.  * only contain ignorable whitespaces. 
  92.  */  
  93. public static final String CHANGE_IGNORABLE_CHARACTERS_INTO_IGNORABLE_WHITESPACES =  
  94.     "validation/change-ignorable-characters-into-ignorable-whitespaces";  

除通过上面的 SAXReader.setFeature 文件之外 ,我们还可以通过自己的 EntityResolver 来解决这个问题。<o:p></o:p>

PS:这个方法是从凝香小筑BLOG的一编主题是:Do not resolve DTD files when dom4j read xml file 的文章里看到的。地址:http://blog.csdn.net/lessoft/archive/<st1:chsdate w:st="on" isrocdate="False" islunardate="False" day="20" month="6" year="2007">2007/06/20</st1:chsdate>/1659579.aspx<o:p></o:p>

代码片断如下:<o:p></o:p>

java 代码
 
  1. saxReader.setEntityResolver(new EntityResolver() {  
  2.       
  3.     String emptyDtd = "";  
  4.                       
  5.     ByteArrayInputStream bytels = new ByteArrayInputStream(emptyDtd.getBytes());  
  6.                       
  7.     public InputSource resolveEntity(String publicId, String systemId)   
  8.            throws SAXException, IOException {  
  9.         return new InputSource(bytels);  
  10.     }  
  11. });  



<o:p> </o:p>

完整的代码如下:<o:p></o:p>

java 代码
 
  1. package test;  
  2.   
  3. import java.io.BufferedWriter;  
  4. import java.io.ByteArrayInputStream;  
  5. import java.io.File;  
  6. import java.io.FileWriter;  
  7. import java.io.IOException;  
  8.   
  9. import junit.framework.TestCase;  
  10.   
  11. import org.dom4j.Document;  
  12. import org.dom4j.DocumentHelper;  
  13. import org.dom4j.Element;  
  14. import org.dom4j.io.OutputFormat;  
  15. import org.dom4j.io.SAXReader;  
  16. import org.dom4j.io.XMLWriter;  
  17. import org.dom4j.tree.DefaultDocumentType;  
  18. import org.xml.sax.EntityResolver;  
  19. import org.xml.sax.InputSource;  
  20. import org.xml.sax.SAXException;  
  21.   
  22. import com.sun.org.apache.xerces.internal.impl.Constants;  
  23.   
  24. /** 
  25.  * A test case class for read and writer a xml file by Dom4j. 
  26.  * @author X.F.Yang [2007/07/03] 
  27.  * @version 1.0 
  28.  */  
  29. public class OperateXmlByDom4jTestCase extends TestCase {  
  30.   
  31.     /** 
  32.      * Default way to read and writer a xml file by Dom4j. 
  33.      * @throws Exception 
  34.      */  
  35.     public void testWriteXml() throws Exception {  
  36.         XmlFileOperation operation = new XmlFileOperation();  
  37.         operation.writer(new SAXReaderWrapper() {  
  38.             public void operation(SAXReader saxReader) throws Exception {  
  39.                 // Nothing to do.  
  40.             }  
  41.         });  
  42.     }  
  43.   
  44.     /** 
  45.      * Do not resolve DTD files when dom4j read xml file via the set feature.  
  46.      * @throws Exception 
  47.      */  
  48.     public void testWriteXmlSetFeature() throws Exception {  
  49.         XmlFileOperation operation = new XmlFileOperation();  
  50.         operation.writer(new SAXReaderWrapper() {  
  51.             public void operation(SAXReader saxReader) throws Exception {  
  52.                 // http://apache.org/xml/features/nonvalidating/load-external-dtd"  
  53.                 saxReader.setFeature(  
  54.                         Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE,   
  55.                         false);  
  56.             }  
  57.         });  
  58.     }  
  59.       
  60.     /** 
  61.      * Do not resolve DTD files when dom4j read xml file via implement {@link EntityResolver}.  
  62.      * @throws Exception 
  63.      */  
  64.     public void testWriteXmlEntityResolver() throws Exception {  
  65.         XmlFileOperation operation = new XmlFileOperation();  
  66.         operation.writer(new SAXReaderWrapper() {  
  67.             public void operation(SAXReader saxReader) throws Exception {  
  68.                 saxReader.setEntityResolver(new EntityResolver() {  
  69.                       
  70.                     String emptyDtd = ""; 
  71.                      
  72.                     ByteArrayInputStream bytels = new ByteArrayInputStream(emptyDtd.getBytes()); 
  73.                      
  74.                     public InputSource resolveEntity(String publicId, 
  75.                             String systemId) throws SAXException, IOException { 
  76.                         return new InputSource(bytels); 
  77.                     } 
  78.                 }); 
  79.             } 
  80.         }); 
  81.     } 
  82.      
  83.     /** */ 
  84.     protected interface SAXReaderWrapper { 
  85.          
  86.         /** operation {@link SAXReader} */ 
  87.         void operation(SAXReader saxReader) throws Exception; 
  88.          
  89.     } 
  90.      
  91.     /**  
  92.      * when the target file was existed, read and append the new element. 
  93.      * else, create a new xml file and add the new element. 
  94.      */ 
  95.     protected class XmlFileOperation { 
  96.          
  97.         /** target file */ 
  98.         private File file; 
  99.          
  100.         public XmlFileOperation() { 
  101.             // target file 
  102.             file = new File("d:\\spring.xml"); 
  103.         } 
  104.          
  105.         /** 
  106.          * Write xml file 
  107.          * @param wrapper  
  108.          * @throws Exception 
  109.          * @see {@link SAXReaderWrapper} 
  110.          */ 
  111.         public void writer(SAXReaderWrapper wrapper) throws Exception { 
  112.             try { 
  113.                 Document document = null; 
  114.                 Element root = null; 
  115.                  
  116.                 // read the xml file if target file was existed  
  117.                 if (file.exists()) { 
  118.                     SAXReader reader = new SAXReader(false); 
  119.                      
  120.                     wrapper.operation(reader); 
  121.                      
  122.                     document = reader.read(file); 
  123.                     root = document.getRootElement(); 
  124.                 // if the target file was not existed, create a new one 
  125.                 } else { 
  126.                     document = DocumentHelper.createDocument(); 
  127.                     document.setDocType(new DefaultDocumentType("beans",  
  128.                             "-//SPRING//DTD BEAN//EN",   
  129.                             "http://www.springframework.org/dtd/spring-beans.dtd"));  
  130.                     root = document.addElement("beans"); 
  131.                 } 
  132.                 // create the element under the root element 
  133.                 root.addElement("bean") 
  134.                     .addAttribute("id", "OperateXmlByDom4jTestCase") 
  135.                     .addAttribute("class", "test.OperateXmlByDom4jTestCase");  
  136.                   
  137.                 // writer the document  
  138.                 writer(document);  
  139.             } catch (Exception e) {  
  140.                 e.printStackTrace();  
  141.                 throw e;  
  142.             }  
  143.         }  
  144.           
  145.         protected void writer(Document document) throws Exception {  
  146.             XMLWriter xmlWriter = null;  
  147.             try {  
  148.                 final OutputFormat format = OutputFormat.createPrettyPrint();  
  149.                 xmlWriter = new XMLWriter(new BufferedWriter(new FileWriter(file)), format);  
  150.                 xmlWriter.write(document);  
  151.             } finally {  
  152.                 if (null != xmlWriter) {  
  153.                     xmlWriter.flush();  
  154.                     xmlWriter.close();  
  155.                 }  
  156.             }  
  157.         }  
  158.     }  
  159. }  
分享到:
评论

相关推荐

    Java and XML, 3rd Edition

    《Java与XML》(第三版)的内容涵盖了所有主要的Java XML处理库程序,全面讲解了SAX、DOM、StAX、JDOM以及dom4j的应用程序编程接口,同时还囊括了最新版本的用于XML处理的Java应用程序编程接口(JAXP)和用于XML绑定...

    XML入门经典(第4版).part1.rar

    《XML入门经典(第4版)》主要内容:创建XML文档必须遵循的规则,如何创建和使用XML标记,提取信息并将其换为HTML或其他格式的方法,存储和读取XML文档的策略,如何使用DOM和SAM操作XML文档,使用Ajax技术、RSS和SOAP...

    android xml解析1

    在JAVA中有两种常见的XML解析方式,DOM和SAX,DOM在解析的时候会将所有的数据一次性载入内存中进行解析,在数据量比较大的情况下,效率非常低.尤其在手机这种对内存和性能要求比较苛刻的设备里面这种方法并不可取. ...

    JAVA与XML.rar

    《Java与XML》(第三版)的内容涵盖了所有主要的Java XML处理库程序,全面讲解了SAX、DOM、StAX、JDOM以及dom4j的应用程序编程接口,同时还囊括了最新版本的用于XML处理的Java应用程序编程接口(JAXP)和用于XML绑定...

    Tinyxml 源代码(VC6 & VS2005)

    从流中读取XML使其可用于网络传输。通过些小技巧,它知道当XML文档读取完毕时,流后面的就一定是其它数据了。TinyXML总假定当它读取到根结点后XML数据就结束了。换句话说,那些具有不止一个根元素的文档是无法被正确...

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

    在XML和DTD文件中,第一个定义的都是根元素。 3.Parent Element(父元素)/Child Element(子元素) 父元素是指包含有其它元素的元素,被包含的元素称为它的子元素。看上面的"结构树",其中是父元素,,是它的子元素,...

    C# XML入门经典

     第4章 在.NET中读取XML  第5章 在.NET中编写XML  第6章 在.NET中实现DOM  第7章 XPath和.NET  第8章 XSLT  第9章 在.NET中使用XSLT  第10章 XML模式—背景知识、语言和一般用法  第11章 XML...

    XML入门经典(第4版).part4.rar

    《XML入门经典(第4版)》主要内容:创建XML文档必须遵循的规则,如何创建和使用XML标记,提取信息并将其换为HTML或其他格式的方法,存储和读取XML文档的策略,如何使用DOM和SAM操作XML文档,使用Ajax技术、RSS和SOAP...

    DWR.xml配置文件说明书(含源码)

    DWR 自动将DOM、DOM4J、JDOM和XOM转换成DOM树,前面这几种类型都仅仅返回Document,Element,Node.DWR会自动将这些转换成浏览器DOM对象.通常在启动JDOM Converter时会有一个提示信息,除非你想采用JDOMconverter否则可以...

    XML入门经典(第4版).part3.rar

    《XML入门经典(第4版)》主要内容:创建XML文档必须遵循的规则,如何创建和使用XML标记,提取信息并将其换为HTML或其他格式的方法,存储和读取XML文档的策略,如何使用DOM和SAM操作XML文档,使用Ajax技术、RSS和SOAP...

    XML入门经典(第4版).part2.rar

    《XML入门经典(第4版)》主要内容:创建XML文档必须遵循的规则,如何创建和使用XML标记,提取信息并将其换为HTML或其他格式的方法,存储和读取XML文档的策略,如何使用DOM和SAM操作XML文档,使用Ajax技术、RSS和SOAP...

    xml入门教程/xml入门教程

    --这一句一定要求写在文件的第一行--&gt; &lt;!--只能有一个根元素即那一对根标签--&gt; &lt;root&gt;&lt;!--根标签--&gt; &lt;!--根元素的内容--&gt; &lt;leaf&gt;&lt;!--子元素--&gt; ... XML文件的写法 xml文档是有标签和标签中的内容组成的,标签和...

    1.ASP.NET.2.0.XML.高级编程(第3版) [1/3]

    \r\n 3.1.11 XML和ADO.NET\r\n 3.1.12 ASP.NET配置 \r\n 3.2 小结 \r\n第4章 用XmlReader和XmlWriter读写XML数据\r\n 4.1 XML的读取器和书写器\r\n 4.2 使用XmlReader类读取XML\r\n 4.2.1 XmlReader简介 ...

    C#XML入门经典 C#编程人员必备的XML技能.part2

    在.NET中读取XML &lt;br&gt;4.1 流模型 4.1.1 流模型和DOM的比较 4.1.2 流模型中的变体 4.2 XmlTextReader类 4.2.1 XmlTextReader属性 4.2.2 读取属性 4.2.3 读取较大的数据块 4.3 XmlNodeReader...

    XML技术 ppt

    126页 XML 简介 编写 XML 文档 使用 DTD 验证 XML 文档 使用 Schema 定义和验证 XML 文档 了解 XML 命名空间 使用 XSLT 转换 XML 文档 使用 DOM 读取和操作 XML 文档 使用 SAX 读取 XML 文档

    SAX是一个用于处理XML事件驱动的“推”模型,虽然它不是W3C标准,但它却是一个得到了广泛认可的API。SAX解析器不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。

    用于访问XML DTD内容的DTDHandler;  ● 用于低级访问解析错误的ErrorHandler;  ● 用于访问文档内容的ContentHandler,这也是最普遍使用的事件处理器。

    php解析xml 的四种简单方法(附实例)

    XML处理是开发过程中经常遇到的,PHP对其也有很丰富的支持,本文只是对其中某几种解析技术做简要说明,包括:Xml parser, SimpleXML, XMLReader, DOMDocument。 1。 XML Expat Parser: XML Parser使用Expat XML解析...

    javascript读取Xml文件做一个二级联动菜单示例

    代码如下: &lt;!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”&gt; &lt;... &lt;head&gt; &lt;title&gt;.../title&gt;... [removed] function ... try{ //IE xmlDoc=new ActiveXObject(“Microsoft.XMLDOM”

Global site tag (gtag.js) - Google Analytics