今天在写使用dom4j增加元素的子节点和兄弟节点,遇到一个问题:新增的子节点,自带xmlns="" 的属性,导致程序报错。
百度良久,终于找到了解决方法,记录下来,以便后面参考,也提供给其他读者参考。
当父节点具有XMLNS属性时,子节点必须指定XMLNS属性,但是当子节点的XMLNS属性与父节点命名空间相同时,子节点不显示XMLNS属性,上面问题的根本所在就是我们理解上的错误,我们认为没有为子节点指定命名空间,就不应该出现此属性,恰恰相反,当我们为其指定与父节点相同的命名空间时,此属性才不会出现。
如下所示:
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="Table Dataset 1" uuid="d8b83813-50b2-4ee6-946a-89f74076070a">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{userList})]]></dataSourceExpression>
</datasetRun>
<jr:column width="90" uuid="21ae79ae-dca2-4c43-b531-98b34f2f02bf">
<jr:columnHeader style="table_CH" height="30">
<staticText>
<reportElement x="0" y="0" width="90" height="30" uuid="db839944-81d0-4d33-be60-843c1bcfbecc"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<text><![CDATA[用户id]]></text>
</staticText>
</jr:columnHeader>
<jr:detailCell style="table_TD" height="20">
<textField>
<reportElement x="0" y="0" width="90" height="20" uuid="2fbcb727-b009-44fd-bd8e-02c306711fa9"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{uid}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
要增加一个新的jr:column节点,要指定jrcolumn的命名空间为jr:table即它的父节点的命名空间:
Map map = new HashMap();
map.put("jr","http://jasperreports.sourceforge.net/jasperreports/components");
//创建解析器对象
SAXReader saxReader = new SAXReader();
File file = new File(filePath);
saxReader.getDocumentFactory().setXPathNamespaceURIs(map);
//得到document
Document document = saxReader.read(file);
Element root = document.getRootElement();
//获取到jr:table节点
List tableList = document.selectNodes("//jr:table");
Element table = (Element)tableList.get(0);
//获取jr:table下面的所有元素
List<Element> columns = table.elements();
//创建一个新的column节点
Element newColumn = DocumentHelper.createElement(QName.get("column", table.getNamespace ()));
关键代码:Element newColumn = DocumentHelper.createElement(QName.get("column", table.getNamespace ()));
指定新增的节点命名空间与父节点的相同,那么新增节点中带jr:*的节点就不会出现xmlns=""的情况,但是不带有jr的节点反而出现的xmlns=""的属性,像staticText和TextField节点,那么需要指定为不带有jr标签的命名空间,因为这个xml的根节点jasperReport不是以jr:开头的,所以我取了根节点的命名空间即:
Element staticText = columnHeader.addElement(QName.get("staticText", root.getNamespace ()));
测试了一下,没有生成xmls:""的属性,问题解决。