0

I've searched but couldn't find what I need.

I need to open a XML file stored on FTP, then I have to list all nodes and insert a new one.

Look at the following XML example.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>data2</loc>
        <priority>1.0</priority>
    </url>

    <url>
        <loc>data1</loc>
         <priority>1.0</priority>
    </url>
</urlset>

I am retrieving the file:

    String filename = "test.xml";
    String server = "...";
    int port = 21;
    String user = "...";
    String pass = "...";

    FTPClient ftpClient = new FTPClient();
    ftpClient.connect(server, port);
    ftpClient.login(user, pass);

    ftpClient.enterLocalPassiveMode();

    /*filePath deve ser o ftp?*/
    FileOutputStream fos = new FileOutputStream(filename);
    ftpClient.retrieveFile("folder/" + filename, fos);

Now, I would like to append another XML node inside this file, getting the following result for example: What means that I want to append before the 1st element of the XML -> n.insertBefore(NODE, n.getFirstChild()); Then save it on FTP again.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>data3 - NEW DATA</loc>
        <priority>1.0</priority>
    </url>
    <url>
        <loc>data2</loc>
        <priority>1.0</priority>
    </url>

    <url>
        <loc>data1</loc>
         <priority>1.0</priority>
    </url>
</urlset>

I know that it is possible to do downloading the file, opening, appending and then uploading it. But in my case I can't do that. I must append the file instead overwritte it.

I can do this on LOCAL file stored as the following.

public class XMLWriter {

     /*
     * @param args the command line arguments
     */

    public static void main(String[] args) throws Exception 
    {
        MethodWrite2();
    }


    public static void MethodWrite2() throws org.xml.sax.SAXException, TransformerException, IOException, ParserConfigurationException
    {          
        String filePath = "teste.xml";
        File xmlFile = new File(filePath);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;

        dBuilder = dbFactory.newDocumentBuilder();
        Document doc;
        doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();

        Node n = doc.getElementsByTagName("urlset").item(0);
        ContadorDeNosXml(doc); // count Node numbers and print the content of an attribute of each node
        /*cria uma lista de especiais a serem adicionados no XML*/
        List<NovoEspecial> listaDeNovosEspeciais = new ArrayList<NovoEspecial>();


        /*loop para adicionar um novo especial a lista de novos especiais que serão adicionados no XML*/
        /*necessário correção -> OBS nr: (1)*/
        for (int i = 0 ; i <= 10; i++)
        {
            /*pra cada 1, cria uma instancia e adiciona a lista de novos especiais a serem adicionados no XML*/
             NovoEspecial novoEspecial = new NovoEspecial("data", Integer.toString(i));
             listaDeNovosEspeciais.add(novoEspecial);
        }

        /*pra cada item da lista de novos especiais a serem adicionados no XML*/
        for(NovoEspecial novoEspecial : listaDeNovosEspeciais)
        {   
            Element urlTag = CreateXmlNode(doc, novoEspecial);          
            // INSERE NO INICIO/ANTES DO PRIMEIRO ELEMENTO, DESSA FORMA FICANDO DO MAIS NOVO PARA O MAIS ANTIGO
            n.insertBefore(urlTag, n.getFirstChild());   
        }

        doc.getDocumentElement().normalize();

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();

        //SETA IDENTAÇÃO NO PADRAO DO XML.APACHE COM 4 ESPAÇOS
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

        DOMSource domSource = new DOMSource(doc);
        StreamResult streamResult = new StreamResult(filePath);            
        transformer.transform(domSource, streamResult);

    } //MethodWrite2


    public static Element CreateXmlNode(Document doc, NovoEspecial novoEspecial)
    {
        // CRIA A TAG URL
        Element urlTag = doc.createElement("url");
        // CRIA A TAG LOC E ESCREVE DENTRO DELA O LINK DO NOVO ESPECIAL
        Element loc = doc.createElement("loc");
        loc.appendChild(doc.createTextNode(novoEspecial.getUrl()));

        //CRIA A TAG PRIORITY E ESCREVE DENTRO DELA O VALOR ATRIBUIDO
        Element priority = doc.createElement("priority");
        priority.appendChild(doc.createTextNode( novoEspecial.getPriority()));

        // ADICIONA AS TAGS PRIORITY E LOC DENTRO DA TAG URL
        urlTag.appendChild(loc);
        urlTag.appendChild(priority);

        return urlTag;
    }

    public static void ContadorDeNosXml(Document doc)
    {
        NodeList nodeLst = doc.getElementsByTagName("url");
        List<NovoEspecial> listaDeNovosEspeciais = new ArrayList<NovoEspecial>();
        System.out.println(nodeLst.getLength());

        for(int i =0; i < nodeLst.getLength(); i++)
        {
            Node locNode = doc.getElementsByTagName("loc").item(i);
            Node priorityNode = doc.getElementsByTagName("priority").item(i);

            NovoEspecial novoEspecial = new NovoEspecial(locNode.getTextContent(), priorityNode.getTextContent());

            System.out.println("ContadorDeNosXml URL = " + novoEspecial.getUrl() );
            System.out.println("ContadorDeNosXml Priority = " + novoEspecial.getPriority());
        }
    }
}

public class NovoEspecial
{
    private String url;
    private String priority;

    //constructor
    protected NovoEspecial(String url, String priority)
    {
        setUrl(url);
        setPriority(priority);
    }

    //getters
    public String getUrl()
    {
        return url;
    }
    public String getPriority()
    {
        return priority;
    }

    //setters
    private void setUrl(String url)
    {
        this.url = url;
    }
    private void setPriority(String priority)
    {
        this.priority = priority;
    }
}

Thanks for the help.

Searchs:

How can I write to a remote file using Apache Commons Net?

How do I append a node to an existing XML file in java

How to read and write xml files?

How to append text to an existing file in Java

Daniel Nicolay
  • 153
  • 1
  • 7
  • *"I must append the file instead overwritte it"* Since XML documents have a single root node, and added node must be inserted *before* the end-tag of the root node, which means you cannot add a node using append only. What you're asking is impossible. – Andreas Aug 29 '18 at 19:13
  • So, I have to download the file and work with it as a local file and then upload it? – Daniel Nicolay Aug 29 '18 at 19:22
  • That is correct. Note that, depending on FTP library you're using, you don't have to down to *file*. You can down as stream, and parse the stream directly, e.g. to DOM. Then modify the DOM and upload directly, without ever creating a local file. – Andreas Aug 29 '18 at 19:23
  • Ok. I am using FTPClient from org.apache.commons.net.ftp. Could you tell me how I parse the stream to DOM using this library? Thanks for the answer – Daniel Nicolay Aug 29 '18 at 19:34
  • **Read the documentation**, i.e. the javadoc of [`FTPClient`](https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html), and you see `retrieveFileStream` *right next to* `retrieveFile`. – Andreas Aug 29 '18 at 19:53

0 Answers0