Задача от Алексея. По работе часто приходится сталкиваться с задачей по обработке XML сообщений. Заменить теги, значение тегов, размаршалить и тд. Формат XML очень популярная тема для обмена сообщениями, рассмотрим несколько примеров возможной работы с этим форматом.
Задание:
Имеем csv/txt файл с набором данных. Распарсить файл, собрать XML сообщение. Сохранить в файл.
Из полученной XML достать объекты (распарсить XML) несколькими способами. Заменить значение тегов в XML у исходной и сохранить новую XML.
Заменить блок значений в XML (добавить/удалить). Изменить наименование тега в XML.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <ActorCast xmlns="https://www.gotoqa.ru/actors"> <Cast id="1"> <Character> <FirstName>Daenerys</FirstName> <LastName>Targaryen</LastName> </Character> <Actor> <FirstName>Emilia</FirstName> <LastName>Clarke</LastName> <BirthDay>23 October 1986</BirthDay> </Actor> </Cast> </ActorCast> |
Также в XML
– id = 2, сменить на id = 20;
– У актера id = 2, сменить блок Character;
– Добавить блок Cast id=”21″ с произвольными данными;
– Удалить блок Cast id=”10″;
Использовал:
SAX | DOM | XPath |
Начать нужно с теории по XML: w3schools
Кода получилось много, поэтому выложу отрывки и как всегда полный проект доступен на GitHub
SAX Parser
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); DefaultHandler handler = new DefaultHandler() { boolean bfname = false; boolean blname = false; boolean birthDay = false; public void startElement(String uri, String localName, String qName, Attributes attributes) { System.out.println("Start Element: " + qName); if (qName.equalsIgnoreCase("FIRSTNAME")) { bfname = true; } if (qName.equalsIgnoreCase("LASTNAME")) { blname = true; } if (qName.equalsIgnoreCase("BirthDay")) { birthDay = true; } |
DOM Parser
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("D:\\JAVA\\Java_SRC\\XMLParsingProject\\src\\main\\resources\\act.xml"); DocumentTraversal trav = (DocumentTraversal) document; MyFilter filter = new MyFilter(); NodeIterator it = trav.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, filter, true); for (Node node = it.nextNode(); node != null; node = it.nextNode()) { String name = node.getNodeName(); String text = node.getTextContent().trim().replaceAll("\\s+", " "); System.out.printf("%s: %s%n", name, text); System.out.println("=========================================="); } |
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(xmlFilePath); Node employee = document.getElementsByTagName("Cast").item(1); NamedNodeMap attribute = employee.getAttributes(); Node nodeAttr = attribute.getNamedItem("id"); nodeAttr.setTextContent("20"); Node nodeAttr2 = document.getElementsByTagName("FirstName").item(0); nodeAttr2.setTextContent("FnameUPDATE"); Node nodeAttr3 = document.getElementsByTagName("LastName").item(0); nodeAttr3.setTextContent("LnameUPDATE"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); |
String filePath = "D:\\JAVA\\Java_SRC\\XMLParsingProject\\src\\main\\resources\\act.xml"; File xmlFile = new File(filePath); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder; try { dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(xmlFile); doc.getDocumentElement().normalize(); System.out.println("Root element: " + doc.getDocumentElement().getNodeName()); NodeList nodeList = doc.getElementsByTagName("Actor"); List<ActorsModel> actorsList = new ArrayList<>(); for (int i = 0; i < nodeList.getLength(); i++) { actorsList.add(getActors(nodeList.item(i))); } for (ActorsModel act : actorsList) { System.out.println(act.getFirstName().toString()); } |
XPATH Parser
XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//*[local-name()='BIC'][" + i + "]" + "//*[local-name()='BIC'][\" +i+ \"]"); String nodes = (String) expr.evaluate(doc, XPathConstants.STRING); |
Ссылка на GitHub:
Github XML Parsing (SAX, DOM, XPath)