XML - расширенный язык разметки, как говорит википедия. Используется он сейчас практически везде: и в качестве конфигурационных файлов, и для импорта/экспорта и для приема/передачи. Всё это весело и удобно.
Итак, ниже кое что из того, что я ноковырял...
для работы с XML я использовал следующие пакеты:
Проверка документа
На этом этапе мы можем проверить xml файл на соответствие XML Schema(xsd), если такая предусмотрена (про xsd можно почитать тут, тут и тут. Если коротко, то это своеобразный шаблон xml-документа). Да и вообще, на правильность синтаксиса.
Подготовка
Продолжаем. создаем объект в котором будет храниться наш распарсеный xml-документ:
теперь мы можем работать с нашим документом.
Получение данных
Работая с объектами Document, мы работаем с DOM. XML-документ в этих объектах представлен в виде дерева, которое обходится рекурсивной функцией. Ниже приведен пример работы. В нем осуществляется обход XML и инициализируется массив объектов.
Анализируемый XML:
Добавление элементов
Допустим, мы хотим добавить в хмл, приведенный выше, следующее:
Итак, ниже кое что из того, что я ноковырял...
для работы с XML я использовал следующие пакеты:
import javax.xml.*; import org.w3c.dom.*; import org.xml.sax.SAXException;Открываем файл ():
File xmlfile = new File("Sites.xml");
Проверка документа
На этом этапе мы можем проверить xml файл на соответствие XML Schema(xsd), если такая предусмотрена (про xsd можно почитать тут, тут и тут. Если коротко, то это своеобразный шаблон xml-документа). Да и вообще, на правильность синтаксиса.
//создаем фабрику SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); //открываем файл со схемой, инициализируем схему, инициализируем валидатор File loc = new File("Site.xsd"); Schema schema = factory.newSchema(loc); Validator validator = schema.newValidator(); //специфический объект для хранения проверяемого xml Source source = new StreamSource(xmlfile); //непосредственно проверка try { validator.validate(source); System.out.println(xml + " is valid."); } catch (SAXException ex) { System.out.println(xml + " is not valid because "); System.out.println(ex.getMessage()); }
Подготовка
Продолжаем. создаем объект в котором будет храниться наш распарсеный xml-документ:
Document doc = null;Создаем и инициализируем фабрику для парсинга документа:
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance(); DocumentBuilder db = f.newDocumentBuilder();Разбираем документ и записываем результат в doc
try { doc = db.parse(file); } catch (IOException e) { System.out.println("Error!"); return; }
теперь мы можем работать с нашим документом.
Получение данных
Работая с объектами Document, мы работаем с DOM. XML-документ в этих объектах представлен в виде дерева, которое обходится рекурсивной функцией. Ниже приведен пример работы. В нем осуществляется обход XML и инициализируется массив объектов.
Анализируемый XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <p:Sites xmlns:p="http://www.example.org/Site" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/Site Site.xsd "> <Site> <Name>Первый сайт</Name> <Type>Рекламный</Type> <Chars> <Email>true</Email> <News>true</News> <Arch>true</Arch> <Votes>анонимно</Votes> <Free>true</Free> </Chars> <Authorize>true</Authorize> </Site> <Site> <Name>Второй сайт</Name> <Type>страница новостей</Type> <Chars> <Email>true</Email> <News>true</News> <Arch>true</Arch> <Votes>анонимно</Votes> <Free>true</Free> </Chars> <Authorize>true</Authorize> </Site> </p:Sites>А теперь пример обработки:
static Site tempsite = new Site(); public static void initDom(Node node,String parent) // Node - узел дерева { //анализируем тип узла int type = node.getNodeType(); // switch (type) { case Node.DOCUMENT_NODE: // фактически - корень документа { initDom(((Document)node).getDocumentElement(),""); break; } case Node.ELEMENT_NODE: //элемент { //для данного примера "Site" - основной элемент, сколько таких элементов в XML, столько объектов в нем описано if (node.getNodeName()=="Site") { sitescount++; tempsite = new Site(); } //если у элемента есть вложенные элементы, обходим по всем if (node.hasChildNodes()) { NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) initDom(children.item(i),node.getNodeName()); } //предыдущий заполнен и может быть добавлен в массив if (node.getNodeName()=="Site") { sites.add( tempsite); } break; } //Значения атрибутов. parant - имя атрибута case Node.TEXT_NODE: { if (parent=="Name") { tempsite.setName(node.getNodeValue()); //получаем значение } if (parent=="Authorize") { tempsite.setAuthorize(Boolean.getBoolean(node.getNodeValue())); } if (parent=="Email") { tempsite.getChars().email=Boolean.getBoolean(node.getNodeValue()); } if (parent=="Arch") { tempsite.getChars().arch=Boolean.getBoolean(node.getNodeValue()); } if (parent=="News") { tempsite.getChars().news=Boolean.getBoolean(node.getNodeValue()); } if (parent=="Free") { tempsite.getChars().free=Boolean.getBoolean(node.getNodeValue()); } if (parent=="Type") { tempsite.setType(node.getNodeValue()); } if (parent=="Votes") { tempsite.getChars().vote=node.getNodeValue(); } break; } } }Структуру объекта Site я не привожу, ибо она проста и понятна из выше приведенного кода. Главное - понять алгоритм обработки, показанный в примере.
Добавление элементов
Допустим, мы хотим добавить в хмл, приведенный выше, следующее:
<Site> <Name>New site</Name> </Site>Первым делом создаем объект, являющийся корневым узлом нашего xml-дерева
Element root = doc.getDocumentElement();Затем создаем необходимые элементы:
Element elem = doc.createElement("Site"); Element elem2 = doc.createElement("Name");Создаем "текстовый узел". Т.е. по сути - значение. То, что находится между тегами
Text value = doc.createTextNode("New site");Теперь нам надо задать подчиненность (что из описанных элементов основное, а что внутри).
elem2.appendChild(value); elem.appendChild(elem2);И все это должно быть внутри корневого элемента:
root.appendChild(elem);И последним шагом мы должны переписать физический xml-файл. Без этого мы сможем работать с документом, но как только приложение завершит работу, все изменения будут потеряны.
TransformerFactory tranformerFactory = TransformerFactory.newInstance(); Transformer tr = tranformerFactory.newTransformer(); tr.setOutputProperty(OutputKeys.INDENT, "yes"); tr.transform(new DOMSource(doc), new StreamResult(new File("Sites.xml")));Пока всё.