在给定位置向xml文件添加新元素

时间:2013-07-30 08:50:53

标签: java xml jdom

我正在尝试将两个元素添加到xml文件中,我想将它们放在标记之后,以便我创建一个包含属性标记的newchildren列表,然后是新参数,然后是其余的rootnode子项,如下所示:

public void addParameters(Element rootNode) {

    Element resourcesParameter;
    Element subreportsParameter;

    List<Element> children;
    List<Element> newChildren;
    children = rootNode.getChildren("property", Namespace.getNamespace("http://jasperreports.sourceforge.net/jasperreports"));

    System.out.println("AAAAAAAAAAAAAAAAA " + Collections.indexOfSubList(rootNode.getChildren(), children));

    newChildren = rootNode.getChildren().subList(0, children.size());
    System.out.println(" size with property : " + newChildren.size() );

    resourcesParameter =  addParameter("RESOURCES_DIR", "resources");
    newChildren.add(resourcesParameter);
    System.out.println(" size with resources : " + newChildren.size() );


    subreportsParameter =  addParameter("SUBREPORT_DIR", "subreports" );
    newChildren.add(subreportsParameter);
    System.out.println(" size with subreports : " + newChildren.size() );
    for(int i =0; i< newChildren.size(); i++) {
        System.out.println("newchildren element " + i + " :" + newChildren.get(i) );
    }

    List<Element> rest = rootNode.getChildren().subList(children.size() + 2, rootNode.getChildren().size());
    System.out.println(" size rest : " + rest.size() );
    for(int i =0; i< rest.size(); i++) {
        System.out.println(" rest element " + i + " :" + rest.get(i) );
    }

    newChildren.addAll(rest);
    System.out.println("size newchildren : " + newChildren.size() );

    rootNode.getChildren().clear();
    rootNode.getChildren().addAll(newChildren);

}

addParameter方法的代码:

public Element addParameter (String attributeName, String path) {
    Element parameter;
    Element defaultValueExpression;

    parameter = new Element("parameter", "http://jasperreports.sourceforge.net/jasperreports");
    parameter.setAttribute(new Attribute("name", attributeName));
    parameter.setAttribute(new Attribute("class", "java.lang.String"));
    parameter.setAttribute(new Attribute("isForPrompting", "false"));

    defaultValueExpression = new Element("defaultValueExpression", "http://jasperreports.sourceforge.net/jasperreports");
    defaultValueExpression.setContent(new CDATA('"'+ path + File.separator + '"'));

    parameter.addContent(defaultValueExpression);

    return parameter;

}

预期的xml文件应该是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report name" pageWidth="595" pageHeight="842" columnWidth="595" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
<property name="ireport.zoom" value="1.5"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="384"/>
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
    <defaultValueExpression><![CDATA["subreports/"]]></defaultValueExpression>
</parameter>
<parameter name="RESOURCES_DIR" class="java.lang.String" isForPrompting="false">
    <defaultValueExpression><![CDATA["resources/"]]></defaultValueExpression>
</parameter>
<queryString language="xPath">
    <![CDATA[/pages/page]]>
</queryString>
<field name="noClt" class="java.lang.String">
    <fieldDescription><![CDATA[noClt]]></fieldDescription>
</field>
<field name="noFact" class="java.lang.String">
    <fieldDescription><![CDATA[noFact]]></fieldDescription>
</field>
<field name="sarlatLe" class="java.lang.String">
    <fieldDescription><![CDATA[sarlatLe]]></fieldDescription>
</field>
<field name="noPage" class="java.lang.String">
    <fieldDescription><![CDATA[noPage]]></fieldDescription>
</field>
<field name="adresseligne1" class="java.lang.String">
    <fieldDescription><![CDATA[groupeAdresse/ligne1]]></fieldDescription>
</field>
<field name="adresseligne2" class="java.lang.String">
    <fieldDescription><![CDATA[groupeAdresse/ligne2]]></fieldDescription>
</field>
<field name="adresseligne3" class="java.lang.String">
    <fieldDescription><![CDATA[groupeAdresse/ligne3]]></fieldDescription>
</field>
<field name="adresseligne4" class="java.lang.String">
    <fieldDescription><![CDATA[groupeAdresse/ligne4]]></fieldDescription>
</field>
<field name="adresseligne5" class="java.lang.String">
    <fieldDescription><![CDATA[groupeAdresse/ligne5]]></fieldDescription>
</field>
    .....
 </jasperReport>

但是在向新孩子列表添加休息时出现此错误:

Exception in thread "AWT-EventQueue-0" org.jdom2.IllegalAddException: The Content already has an existing parent "jasperReport"
at org.jdom2.ContentList.checkPreConditions(ContentList.java:211)
at org.jdom2.ContentList.add(ContentList.java:244)
at org.jdom2.ContentList$FilterList.addAll(ContentList.java:1067)
at java.util.SubList.addAll(AbstractList.java:684)
at java.util.SubList.addAll(AbstractList.java:674)
at fr.srd.remap.ui.gui.ProjectExporter.addParameters(ProjectExporter.java:387)
at fr.srd.remap.ui.gui.ProjectExporter.prepareProject(ProjectExporter.java:140)
at fr.srd.remap.ui.gui.ProjectExporter.editReportFiles(ProjectExporter.java:208)
at fr.srd.remap.ui.gui.ProjectExporter.editReportFiles(ProjectExporter.java:167)
at fr.srd.remap.ui.gui.ProjectExporter.editReportFiles(ProjectExporter.java:167)
at fr.srd.remap.ui.gui.ProjectExporter.editReportFiles(ProjectExporter.java:167)
at fr.srd.remap.ui.gui.ProjectExporter.prepareProject(ProjectExporter.java:132)
at fr.srd.remap.ui.gui.ProjectExporter.export(ProjectExporter.java:59)

任何人都可以帮我这个吗?

1 个答案:

答案 0 :(得分:1)

试试这个:

newChildren = new ArrayList<Element>(rootNode.getChildren().subList(0, children.size()));