http://asialee.iteye.com/blog/977988
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>
<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>
<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());
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);
- }
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());
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,但是对外并没有提供获得它的方法,不知道有没有别的什么办法来获得它.