1. 在dom4j里,直接在root element上addNamespace是无法成功的,因为是默认的,所以prefix必须给空字符串,结果导致了root的直接子结点都产生了xmlns=""的属性
诸如:
<root xmlns="http://wangf.javaeedev.com"> <blog xmln=""> <aticles>...</aticles> </blog> <forum xmlns=""> <topics>...</topics> </forum> </root>这个可以通过在构造rootElement的时候指定,具体为什么,我想什么时候看看源码???
Element root = maindoc.addElement("root", "http://asialee.javaeeye.com")
2. XSD文件的解析,本来XSD应该是一个特殊的XML,它应该是可以通过XML的方式进行解析的,但是是有问题的.
<SchemaTypes xmlns="http://asialee.javaeeye.com"> <SchemaType> <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="Status"> <xsd:simpleType> <xsd:restriction base="xsd:NMTOKEN"> <xsd:enumeration value="ValidData" /> <xsd:enumeration value="InvalidData" /> <xsd:enumeration value="Accept" /> <xsd:enumeration value="BadCredit" /> <xsd:enumeration value="OverLimit" /> <xsd:enumeration value="BadDataFormat" /> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:schema> </SchemaType> </SchemaTypes>
SAXReader reader = new SAXReader(); Document document = reader.read(xmlFile); Element rootElement = document.getRootElement(); Element schemaType = rootElement.element("SchemaType"); Element xsdElement = (Element)schemaType.elements().get(0); System.out.println(xsdElement.asXML());
dom4j会将elementname识别成xsd:schema,然后再增加一层xsd,返回的xml就变成了xsd:xsd:schema,这个现在还没有找到好的解决办法,我使用的是
replaceAll("\\<xsd:", "<")
.replaceAll("</xsd:", "</")
.replaceAll("xmlns:xsd=\"\"", "")
感觉太恶心了,但是现在只能先这么实现着
还有dom4j好像解析xsd文件比较困难,我实在不想再找另外一个库,然后就先这么实现着,等以后研究了源码再看看.
3. Dom 节点 Atrribute 的顺序问题
dom4j里面的attributes方法返回的是一个List<Attribute>这个比较好,是一个定义顺序。但dom里面的getAttributes()返回的是NamedNodeMap 它按照Attribute的名字,按字典序排序了,这个地方我比较赞dom4j
4. Dom4j里面的Node的transformer是不行了,只能整个document进行转换
来看下javax.xml.transform.Transformer里面的接口
transform(Source xmlSource, Result outputTarget)
但是dom4j只提供了DocumentSource,它是继承javax.xml.transform.dom.Source的再来看看DocumentSource的构造函数,我们传递一个node,它还是得到它的document,这 个来说,如果想要对某个Node进行transform,就显得没有什么好的办法了.
public DocumentSource(Node node) { setDocument(node.getDocument()); } public DocumentSource(Document document) { setDocument(document); }
5. dom4j里面提供了SAXReader和DomReader,这个方式就是既可以用dom也可以使用
sax来进行读取,但是如果用dom的形式,如果要进行xml的validation,就显得不太好弄了.
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setFeature("http://apache.org/xml/features/continue-after-fatal-error",true); DocumentBuilder builder = null; if(isValidationON){ builderFactory.setFeature("http://xml.org/sax/features/validation",true); builderFactory.setFeature("http://apache.org/xml/features/validation/schema",true); builder = builderFactory.newDocumentBuilder(); builder.setEntityResolver(new MyDefaultEntityResolver()); } else { builder = builderFactory.newDocumentBuilder(); } builder.setErrorHandler(new MyDefaultParsingErrors());
是因为feature要设置再builderFactory里面,然后entityRelver要设置再builder上面。这样就显得特别别扭。因为DocumentBuilder,底层有一个DomParser,但是对外并没有提供获得它的方法,不知道有没有别的什么办法来获得它.