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")));
Пока всё.