Как правильно хранить данные в XML и добавлять новые узлы к нему? - PullRequest
0 голосов
/ 06 ноября 2019

Введение

Этот вопрос является частью старого проекта, который я сделал для школы, который прошел отлично, но не смог получить желаемый результат, когда речь шла о сохранении новых данных в файле XML. ,Программа работает как задумано, но это последнее, что делает ее неполной для меня.

Проблема

Даже если я загружаю объект Document с файлом XML, как указано в этот вопрос

Document doc = documentBuilder.parse(new File("src\\xmlfolder\\productes.xml"));

Я не могу получить желаемый результат отформатированного XML-файла, поскольку есть некоторые скрытые пробелы, которые портят XML-файл, загруженный в объект Document.

Пример проблемы

<productes>

    <producte codi="100">

        <nom>producte100</nom>

        <preu>1534</preu>

        <unitats>3</unitats>

    </producte>

    <producte codi="110">

        <nom>producte110</nom>

        <preu>578</preu>

        <unitats>7</unitats>

    </producte>

    <producte codi="120">

        <nom>producte120</nom>

        <preu>666</preu>

        <unitats>1</unitats>

    </producte>

    <producte codi="166">

        <nom>caca</nom>

        <preu>200</preu>

        <unitats>4</unitats>

    </producte>

    <producte codi="266">
        <nom>test</nom>
        <preu>100</preu>
        <unitats>1</unitats>
    </producte>
</productes>

Каждый раз, когда я добавляю новый продукт (, нижний элемент - новый ), те, что перед ним, получают отступы все больше и больше, когда я продолжаю добавлять продукты. Как это!?

Моя попытка бороться с этим

Как я уже говорил, мой код работает отлично и выполняет свою работу (добавление / удаление и изменениеДанные XML), но эта последняя особенность, , предвосхищающая XML - это то, что я хотел . До сих пор я использовал это, чтобы хранить данные только в одной строке, но, как вы можете себе представить ... Предпочитается структурировать.

   TransformerFactory transformerFactory = TransformerFactory.newInstance();
   Transformer transformer = transformerFactory.newTransformer();
   DOMSource source = new DOMSource(doc);
   StreamResult result = new StreamResult(xmlfile);
   transformer.transform(source, result);

Некоторые идеи появились благодаря этому и этому вопросу. Но ни один из них, похоже, не сработал, или у меня нет опыта, чтобы правильно применить его к моей проблеме, или я упускаю что-то критическое, на что нужно указать.

Для тех, у кого здесь такие же вопросы, и которые заканчиваются наЗдесь я собираюсь поделиться полным кодом, надеясь, что он поможет вам в этом вопросе.

Полный код

public class GestioProductes {

private File xmlfile = new File("xmls/productes.xml");


private void setFilePath(String path)
{
    this.xmlfile = new File(path);
}

private String getAbsFilePath()
{
    return this.xmlfile.getAbsolutePath();
}

private String getPath()
{
    return this.xmlfile.getPath();
}

/**
* Fetch a product given a node
* */
private  Producte getProducte(Node node) {
    /*
    * Node is an interface that works as primary datatype for DOM. Represents a single node in the doc tree.
    * */
    Producte prod = new Producte();
    if (node.getNodeType() == Node.ELEMENT_NODE)
    {
        Element element = (Element) node;
        prod.setCodi(Integer.parseInt(getAttrbValue("producte", element)));
        prod.setNom(getTagValue("nom", element));
        prod.setPreu(Long.parseLong(getTagValue("preu", element)));
        prod.setUnitats(Integer.parseInt(getTagValue("unitats", element)));
    }
    return prod;
}

/**
 * Gets the values value of a tag from a given element object
 * */
private  String getTagValue(String tag, Element element) {
    NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
    Node node = (Node) nodeList.item(0);
    return node.getNodeValue();
}

/**
* Gets the attribute value of a tag from a given element object
* */
private  String getAttrbValue(String tag, Element element)
{
    return element.getAttribute("codi");
}

/**
 * Aux func to modify a selected tag
 * */
private void setValueElement(String tag, String value, Element e) {

    NodeList nodeList = e.getElementsByTagName(tag);
    Node node = nodeList.item(0);
    //System.out.println("node: " + node.getTextContent());
    node.setTextContent(value);
}

/**Saves the built doc into the XML*/
private void saveFile(Document doc){


    try{

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(xmlfile);
        transformer.transform(source, result);


        //Pass the doc object built and stream it out into the XML file

    } catch (Exception e) {
        System.out.println("[ERROR] on save file");
    }

}


/**
* Loads the data from the XML into Objects
* */
public void loadXML(String path) {
    File xmlfile = new File(path);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;

    try{
        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        //System.out.println("DOC -> " + doc.getDocumentElement().getChildNodes().item(1).getTextContent());
        System.out.println("Root element: " + doc.getDocumentElement().getNodeName());

        //To store nodes
        NodeList nodeList = doc.getElementsByTagName("producte");

        //To store the Product objs
        List<Producte> prodList = new ArrayList<Producte>();

        //Load obj list
        for (int i = 0; i < nodeList.getLength(); i++)
        {
            prodList.add(getProducte(nodeList.item(i)));
        }
        //Lets print employee list
        for (Producte prod : prodList)
        {
            System.out.println(prod.toString());
        }

    } catch (Exception e)
    {
        System.out.println(e);
    }
}

/**
* When adding a product it must be checked beforehand
* */
public boolean initialCodeCheck(Producte prod) {
    System.out.println("Checking availability for code: " + prod.getCodi());

    Scanner scan = new Scanner(System.in);
    String option = "";

    //Before anything else check if the code already exists in the XML
    if (existsCode(prod.getCodi()))
    {
        System.out.println("[WARN] This code (" + prod.getCodi() + ") is already in use for another product");
        return false;
    }
    else
    {
        return true;
    }

}

/**
* Adds a product from a Product obj, before that, checks if it's 'codi' is already being in use
* */
public void addProduct(Producte prod) {

    if(initialCodeCheck(prod))
    {
        DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dbuilder;

        System.out.println("Adding data to the XML: " + xmlfile.getName());

        try {
            //Initial setup of classes to work with XML
            dbuilder = dbfactory.newDocumentBuilder();
            Document doc = dbuilder.parse(xmlfile);
            doc.getDocumentElement().normalize();

            //Root element -> productes
            Element root = doc.getDocumentElement();

            //Get producte tag to start appending
            Element producte = doc.createElement("producte");
            producte.setAttribute("codi", prod.getCodi()+"");

            //Create nom element and Text to append on 'nom' and then to the produce Element
            Element elnom = doc.createElement("nom");
            Text nomT = doc.createTextNode(prod.getNom());
            elnom.appendChild(nomT);

            //Same concept as above
            Element elpreu = doc.createElement("preu");
            Text preuT = doc.createTextNode(prod.getPreu()+"");
            elpreu.appendChild(preuT);

            //Same concept as above
            Element elunitats = doc.createElement("unitats");
            Text unitatsT = doc.createTextNode(prod.getUnitats()+"");
            elunitats.appendChild(unitatsT);

            //Append the createdd Elements into their 'producte' parent
            producte.appendChild(elnom);
            producte.appendChild(elpreu);
            producte.appendChild(elunitats);

            //Get everything together
            root.appendChild(producte);

            //Time to write it into the XML
            saveFile(doc);
            System.out.println("Product added successfully!");
        } catch (Exception e)
        {
            System.out.println("[ERROR] Product could not be loaded " + e);
        }
    } else {
        System.out.println("[INFO] Action was canceled");
    }



}

public void updateProduct(Producte prod) {
    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dbuilder;

    System.out.println("Modifying data");
    try{

        dbuilder = dbfactory.newDocumentBuilder();
        Document doc = dbuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        NodeList nl = doc.getElementsByTagName("producte");
        for (int i = 0; i < nl.getLength(); i++)
        {
            Node node = nl.item(i);
            //System.out.println(node.getTextContent());
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element e = (Element) node;
                //System.out.println("Codi is: " + e.getAttribute("codi") + " Evaluating for: " + prod.getCodi());

                if (e.getAttribute("codi").equals(String.valueOf(prod.getCodi()))) {
                    System.out.println("dsafdaf");
                    setValueElement("nom", prod.getNom(), e);
                    setValueElement("preu", prod.getPreu()+"", e);
                    setValueElement("unitats", prod.getUnitats()+"", e);
                    System.out.println("The values for codi (" + prod.getCodi() + ") have been modified successfully");
                    break;
                }
            }
        }
        saveFile(doc);

        /*
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(xmlfile);
        transformer.transform(source, result);*/

    } catch (Exception e) {
        System.out.println("[ERROR] Product could not be modified " + e);
    }
}

public void deleteProduct(int code) {

    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dbuilder;

    System.out.println("Deleting data");
    try {

        dbuilder = dbfactory.newDocumentBuilder();
        Document doc = dbuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        NodeList nl = doc.getElementsByTagName("producte");
        System.out.println("length: " + nl.getLength());

        for (int i = 0; i < nl.getLength(); i++)
        {
            Node node = nl.item(i);
            //System.out.println(node.getTextContent());
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element e = (Element) node;
                //System.out.println("Codi is: " + e.getAttribute("codi") + " Evaluating for: " + prod.getCodi());

                if (e.getAttribute("codi").equals(code+"")) {
                    e.getParentNode().removeChild(e);
                    System.out.println("Deleted");
                    break;
                }
            }
        }

        saveFile(doc);





    } catch (Exception e) {
        System.out.println(e);
    }


}


/**
* From a given ID find the product inside the XML tree and shows it's data
* */
public void findByID(int codi){

    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dbuilder;

    try {

        dbuilder = dbfactory.newDocumentBuilder();
        Document doc = dbuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        NodeList nl = doc.getElementsByTagName("producte"); //Gets only the 'producte' elements

        for(int i = 0; i < nl.getLength(); i++) //Loop it
        {
            if(nl.item(i).getNodeType() == Node.ELEMENT_NODE) //It's a node? Get it!
            {
                Element el = (Element) nl.item(i); //Lets turn it into an easy parse element

                if (el.getAttribute("codi").equals(codi+"")) //Double check if anything which is not 'producte' got in
                {
                    //Get data
                    String nom = el.getElementsByTagName("nom").item(0).getTextContent();
                    String preu = el.getElementsByTagName("preu").item(0).getTextContent();
                    String unitats = el.getElementsByTagName("unitats").item(0).getTextContent();

                    //Show it!
                    System.out.println("Product found!");
                    System.out.println("ID: " + el.getAttribute("codi") + " Name: " + nom + " Price: " + preu + " Unitats: " + unitats);
                    break;
                }
            }
        }




    } catch (Exception e)
    {
        System.out.println("[ERROR] " + e);
    }



}

/**
* From a given String finds the product inside the XML file
* */
public void findByName(String fecthName){

    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dbuilder;

    try {

        dbuilder = dbfactory.newDocumentBuilder();
        Document doc = dbuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        NodeList nl = doc.getElementsByTagName("producte"); //Gets only the 'producte' elements

        for(int i = 0; i < nl.getLength(); i++) //Loop it
        {
            if(nl.item(i).getNodeType() == Node.ELEMENT_NODE) //It's a node? Get it!
            {
                Element el = (Element) nl.item(i); //Lets turn it into an easy parse element

                if (el.getChildNodes().item(1).getTextContent().equals(fecthName)) //Double check if anything which is not 'producte' got in
                {
                    //Get data
                    String nom = el.getElementsByTagName("nom").item(0).getTextContent();
                    String preu = el.getElementsByTagName("preu").item(0).getTextContent();
                    String unitats = el.getElementsByTagName("unitats").item(0).getTextContent();

                    //Show it!
                    System.out.println("Product found!");
                    System.out.println("ID: " + el.getAttribute("codi") + " Name: " + nom + " Price: " + preu + " Unitats: " + unitats);
                    break;
                }
            }
        }


    } catch (Exception e) {
        System.out.println("[ERROR] " + e);
    }


}

/**
* Checks whether a codi already exists in the XML file
* */
public boolean existsCode(int code) {
    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dbuilder;

    try {

        dbuilder = dbfactory.newDocumentBuilder();
        Document doc = dbuilder.parse(xmlfile);
        doc.getDocumentElement().normalize();

        NodeList nl = doc.getElementsByTagName("producte"); //Gets only the 'producte' elements

        for(int i = 0; i < nl.getLength(); i++) //Loop it
        {
            if(nl.item(i).getNodeType() == Node.ELEMENT_NODE) //It's a node? Get it!
            {
                Element el = (Element) nl.item(i); //Lets turn it into an easy parse element

                if (el.getAttribute("codi").equals(code+"")) //Double check if anything which is not 'producte' got in
                {
                    return true; //breaks here
                }
            }
        }
    } catch (Exception e)
    {
        System.out.println("[ERROR] " + e);
    }

    return false; //Nothing found
}




}

Источники знаний

Примечания:

  • Версия Java: 12

  • IDE используется: IntelliJ

  • Выходфайл может быть сам по себе или другой .xml

  • Код является классом для работы с файлами XML и ООП

  • Я хотел бы некоторый обзор како том, как улучшить свои навыки кодирования и общие знания, которые я должен знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...