如何在java中的特定位置添加节点结构化xml

时间:2014-12-17 11:36:13

标签: java xml parsing sax

需要有关如何在xml中的所需位置添加xml节点的帮助。

例如:

原始xml

<Errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="errors.xsd">
    <Service Name="SYSTEM" Range="0-0299">
        <Type Name="System">
            <Error Name="ERROR1">
                <Code>0001</Code>
                <Description>error1</Description>
            </Error>
            <Error Name="ERROR_OTHER">
            <Code>0</Code>
            <Description>error error</Description>
        </Error>
        <Error Name="ERROR2">
            <Code>0002</Code>
            <Description>error2</Description>
        </Error>
    </Type>
    <Type Name="Security">
        <Error Name="ERROR3">
            <Code>0300</Code>
            <Description>error3</Description>
        </Error>
        <Error Name="ERROR4">
            <Code>0301</Code>
            <Description>error4</Description>
        </Error>
    </Type>
    </Service>
    <Service Name="WEBSVC" Range="1000-1199">
    <Type Name="Data">
        <Error Name="ERROR10">
            <Code>1000</Code>
            <Description>error10</Description>
        </Error>
        <Error Name="ERROR5">
            <Code>1001</Code>
            <Description>error5</Description>
        </Error>
        <Error Name="ERROR6">
            <Code>1004</Code>
            <Description>desc</Description>
        </Error>
    </Type>
    <Type Name="System">
        <Error Name="ERROR7">
            <Code>1200</Code>
            <Description>xyz123</Description>
        </Error>
        <Error Name="ERROR8">
            <Code>1201</Code>
            <Description>abcd</Description>
        </Error>
    </Type>
    <Type Name="Business">
        <Error Name="ERROR9">
            <Code>1400</Code>
            <Description>rrreerer</Description>
        </Error>
        <Error Name="ERROR10">
            <Code>1401</Code>
            <Description>err</Description>
        </Error>
    </Type>
    </Service>
</Errors>

我的要求是添加:

        <Error Name="ERROR_NEW">
            <Code>03019</Code>
            <Description>This is a new error</Description>
        </Error>

在位置,例如错误/服务名称=“WEBSVC”/类型名称=“系统”。这可能会根据要求而有所不同。

所需的xml

<Errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="errors.xsd">
    <Service Name="SYSTEM" Range="0-0299">
        <Type Name="System">
            <Error Name="ERROR1">
                <Code>0001</Code>
                <Description>error1</Description>
            </Error>
            <Error Name="ERROR_OTHER">
            <Code>0</Code>
            <Description>error error</Description>
        </Error>
        <Error Name="ERROR2">
            <Code>0002</Code>
            <Description>error2</Description>
        </Error>
    </Type>
    <Type Name="Security">
        <Error Name="ERROR3">
            <Code>0300</Code>
            <Description>error3</Description>
        </Error>
        <Error Name="ERROR4">
            <Code>0301</Code>
            <Description>error4</Description>
        </Error>
    </Type>
    </Service>
    <Service Name="WEBSVC" Range="1000-1199">
    <Type Name="Data">
        <Error Name="ERROR10">
            <Code>1000</Code>
            <Description>error10</Description>
        </Error>
        <Error Name="ERROR5">
            <Code>1001</Code>
            <Description>error5</Description>
        </Error>
        <Error Name="ERROR6">
            <Code>1004</Code>
            <Description>desc</Description>
        </Error>
    </Type>
    <Type Name="System">
        <Error Name="ERROR7">
            <Code>1200</Code>
            <Description>xyz123</Description>
        </Error>
        <Error Name="ERROR8">
            <Code>1201</Code>
            <Description>abcd</Description>
        </Error>
        **<Error Name="ERROR_NEW">
            <Code>03019</Code>
            <Description>This is a new error</Description>
        </Error>**
    </Type>
    <Type Name="Business">
        <Error Name="ERROR9">
            <Code>1400</Code>
            <Description>rrreerer</Description>
        </Error>
        <Error Name="ERROR10">
            <Code>1401</Code>
            <Description>err</Description>
        </Error>
    </Type>
    </Service>
</Errors>

我正在使用SAX解析器,我能够成功解析文档。

ErrorHandler.java

package com.browser.main.Handler;



import java.util.ArrayList;

import java.util.List;



import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;



import com.browser.main.model.*;





public class ErrorHandler extends DefaultHandler {



    private List<ErrorService> errorServiceList = null;

    private ErrorService errorService = null;

    private List<ErrorType> errorTypeList = null;

    private ErrorType errorType = null;

    private List<ErrorDetails> errorDetailList = null;

    private ErrorDetails errorDetails = null;





    public List<ErrorService> getErrorServiceList() {

    return errorServiceList;

    }



    boolean bService = false;

    boolean bType = false;

    boolean bError = false;

    boolean bCode = false;

    boolean bDesc = false;



    @Override

    public void startElement(String uri, String localName, String qName, Attributes attributes)

        throws SAXException {



    if (qName.equalsIgnoreCase("Service")) {

        errorService = new ErrorService();

        errorService.setServiceName(attributes.getValue("Name"));

        if(errorServiceList == null){

            errorServiceList = new ArrayList<ErrorService>();

        }

    } else if (qName.equalsIgnoreCase("Type")){

        errorType = new ErrorType();

        errorType.setErrorTypeName(attributes.getValue("Name"));

        if(errorTypeList == null){

            errorTypeList = new ArrayList<ErrorType>();

        }

    } else if (qName.equalsIgnoreCase("Error")){

        errorDetails = new ErrorDetails();

        errorDetails.setErrorName(attributes.getValue("Name"));

        if(errorDetailList == null){

            errorDetailList = new ArrayList<ErrorDetails>();

        }

    } else if (qName.equalsIgnoreCase("Code")){

        bCode = true;

    } else if (qName.equalsIgnoreCase("Description")){

        bDesc = true;

    }





    }





    @Override

    public void endElement(String uri, String localName, String qName) throws SAXException {

    if (qName.equalsIgnoreCase("Error")) {

        errorDetailList.add(errorDetails);

    } else if (qName.equalsIgnoreCase("Type")){

        errorType.setErrorsDetailList(errorDetailList);

        errorDetailList = null;

        errorTypeList.add(errorType);

    } else if (qName.equalsIgnoreCase("Service")){

        errorService.setErrorTypeList(errorTypeList);

        errorTypeList = null;

        errorServiceList.add(errorService);

    }

    }





    @Override

    public void characters(char ch[], int start, int length) throws SAXException {



    if (bCode) {

        errorDetails.setErrorCode(new String(ch, start, length));

        bCode = false;

    } else if (bDesc) {

        errorDetails.setErrorDesc(new String(ch, start, length));

        bDesc = false;

    }

    }

}

BrowserMain.java

package com.browser.main;



import java.io.File;

import java.io.IOException;

import java.util.List;



import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;



import org.xml.sax.SAXException;



import com.browser.main.Handler.ErrorHandler;

import com.browser.main.model.*;



public class BrowserMain {



    /**

     * @param args

     */

    public static void main(String[] args) {



        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();

        try {

        SAXParser saxParser = saxParserFactory.newSAXParser();

        ErrorHandler handler = new ErrorHandler();

        saxParser.parse(new File("/uapi-error-en.xml"), handler);

        List<ErrorService> errorServiceList = handler.getErrorServiceList();

        System.out.println(errorServiceList.size());

        } catch (ParserConfigurationException | SAXException | IOException e) {

        e.printStackTrace();

        }
    }
}

请建议我如何到达所需位置并在那里添加节点。提前谢谢。

2 个答案:

答案 0 :(得分:0)

得到了答案。使用过的DOM解析器。

public class XmlAppend {

public static void main(String[] args) {
    try {
        File xmlFile = new File("G:/workspace/UAPIErrorBrowser/uapi-error-en.xml");
        //Create the documentBuilderFactory
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        //Create the documentBuilder
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        //Create the Document  by parsing the file
        Document document = documentBuilder.parse(xmlFile);
        //Get the root element of the xml Document;
        Element documentElement = document.getDocumentElement();
        System.out.println("documentElement:" + documentElement.toString());

        boolean isElement = false; 


        while(!isElement){
            NodeList allTypes =  documentElement.getElementsByTagName("Type");//("Errors");
               for(int i = 0; i < allTypes.getLength(); i++){
                   Node type = allTypes.item(i);
                   if(type.getAttributes().getNamedItem("Name").getTextContent().equalsIgnoreCase("System") && type.getParentNode().getAttributes().getNamedItem("Name").getTextContent().equalsIgnoreCase("WEBSVC")){
                       Element codeElement = document.createElement("Code");
                       codeElement.setTextContent("3200");

                       Element descElement = document.createElement("Description");
                       descElement.setTextContent("this is awesome");

                       Element errorNode = document.createElement("Error");
                       errorNode.setAttribute("Name", "THIS_IS_GREAT");

                       errorNode.appendChild(codeElement);
                       errorNode.appendChild(descElement);

                       type.appendChild(errorNode);
                       isElement = true;
                       break;
                   }


               }

           //if(documentElement.getChildNodes())
       }

        Transformer tFormer = TransformerFactory.newInstance().newTransformer();
//  Set output file to xml
        tFormer.setOutputProperty(OutputKeys.METHOD, "xml");
//  Write the document back to the file
        Source source = new DOMSource(document);
        Result result = new StreamResult(xmlFile);
        tFormer.transform(source, result);


    } catch (TransformerException ex) {
        Logger.getLogger(XmlAppend.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SAXException ex) {
        Logger.getLogger(XmlAppend.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(XmlAppend.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
        Logger.getLogger(XmlAppend.class.getName()).log(Level.SEVERE, null, ex);
    }
}
}

答案 1 :(得分:0)

您可以使用XPath表达式为自己节省一些代码,如下所述: https://stackoverflow.com/a/2811101/2065857