Введение
Этот вопрос является частью старого проекта, который я сделал для школы, который прошел отлично, но не смог получить желаемый результат, когда речь шла о сохранении новых данных в файле 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 и ООП
Я хотел бы некоторый обзор како том, как улучшить свои навыки кодирования и общие знания, которые я должен знать.