DocumentBuilder.parse: примеры (JAVA)
DocumentBuilder.parse(File f): DocumentОписание DocumentBuilder.parse()
Метод DocumentBuilder.parse() из пакета javax.xml.parsers предназначен для преобразования XML-источника в объектную модель DOM (org.w3c.dom.Document). Часто применяется при необходимости программного чтения, анализа и модификации XML-документа в памяти.
Возвращаемое значение: объект org.w3c.dom.Document - корневое представление дерева XML после успешного разбора.
Перегрузки и возможные варианты аргументов:
Document parse(File f)- разбирает XML из файла.Document parse(InputStream is)- принимает поток байтов; кодировка определяется декларацией XML или внешним механизмом.Document parse(InputStream is, String systemId)- как выше, с указанием базового URI для разрешения относительных ссылок.Document parse(String uri)- принимает строку-URL или путь, использует URI-ресурс.Document parse(InputSource is)- гибкий вариант: InputSource может включать Reader, InputStream, systemId и encoding.
Взаимодействие с настройками парсера происходит через DocumentBuilderFactory и DocumentBuilder. Важные параметры, влияющие на поведение parse():
- setNamespaceAware(boolean) - управление поддержкой пространств имен (xmlns).
- setValidating(boolean) - валидация по DTD (если true, может требоваться DTD в документе).
- setIgnoringElementContentWhitespace(boolean) - игнорирование пустого текста при наличии DTD/валидации.
- Через
DocumentBuilderможно установитьEntityResolverдля перехвата внешних сущностей иErrorHandlerдля обработки ошибок при разборе. - Безопасность: рекомендуется явно задавать флаги/фичи, защищающие от XXE, например
factory.setFeature("http://xml.org/sax/features/external-general-entities", false)иXMLConstants.FEATURE_SECURE_PROCESSING.
Исключения, которые может бросать parse():
org.xml.sax.SAXException- при нарушении формата или других ошибках парсинга.IOException- при проблемах ввода-вывода (файл/сеть).IllegalArgumentException- при null-аргументах в некоторых перегрузках.
Примечание: DocumentBuilder и DocumentBuilderFactory создаются через статические фабричные методы JAXP. В реальных проектах часто комбинируется настройка фабрики с последующей установкой обработчиков и фич для безопасного и предсказуемого разбора.
Короткие примеры использования
Пример 1 - разбор файла и вывод имени корневого элемента
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.File;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("example.xml"));
System.out.println(doc.getDocumentElement().getNodeName());
Результат: exampleRoot
Пример 2 - разбор из InputStream с указанием systemId
try (InputStream is = new FileInputStream("example.xml")) {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document d = b.parse(is, new File("example.xml").toURI().toString());
System.out.println(d.getDocumentElement().getTagName());
}
Результат: exampleRoot
Пример 3 - использование InputSource с Reader и кодировкой
Reader r = new InputStreamReader(new FileInputStream("utf8.xml"), "UTF-8");
InputSource src = new InputSource(r);
src.setEncoding("UTF-8");
Document doc = builder.parse(src);
System.out.println(doc.getDocumentElement().getNodeName());
Результат: utfRoot
Пример 4 - разбор по URI (HTTP)
Document doc = builder.parse("https://example.com/data.xml");
System.out.println(doc.getDocumentElement().getNodeName());
Результат: remoteRoot (если доступен и корректен)
Похожие Java-решения и особенности
Вместо DOM-парсинга через DocumentBuilder нередко используются другие подходы:
- SAXParser - потоковый (event-driven) парсер, экономит память при обработке больших файлов, не строит дерево в памяти. Предпочтителен для одноразовой последовательной обработки.
- StAX (XMLStreamReader/ XMLStreamWriter) - pull-парсинг, дает контроль чтения событий и пригоден, когда требуется частичный доступ к документу или более простая логика, чем у SAX.
- JDOM, DOM4J, XOM - альтернативные DOM-реализации с более удобным API и расширенными возможностями; хороши для удобной работы с XML, но требуют дополнительных зависимостей.
- XPath (javax.xml.xpath) - применяется совместно с DOM для выборок узлов; для сложных выборок предпочтительнее, чем ручный обход дерева.
Выбор зависит от задач: DocumentBuilder удобен для модификации и навигации через стандартный DOM API; SAX/StAX - для производительности и низкого потребления памяти; внешние библиотеки - для удобного API и дополнительных функций.
Аналоги в других языках и отличия
Краткие эквиваленты parse()-функции в разных языках с примерами и результатами.
PHP - DOMDocument::load()
$doc = new DOMDocument();
$doc->load('example.xml');
echo $doc->documentElement->nodeName;
Результат: exampleRoot
JavaScript (в браузере) - DOMParser
const parser = new DOMParser();
const doc = parser.parseFromString(xmlString, 'application/xml');
console.log(doc.documentElement.nodeName);
Результат в консоли: exampleRoot
Node.js - xml2js (модуль, конвертирует в JS-объект)
const fs = require('fs');
const xml2js = require('xml2js');
const xml = fs.readFileSync('example.xml', 'utf8');
xml2js.parseString(xml, (err, result) => console.log(result));
Результат: JavaScript-объект, представляющий структуру XML
Python - xml.etree.ElementTree.parse()
import xml.etree.ElementTree as ET
tree = ET.parse('example.xml')
root = tree.getroot()
print(root.tag)
Результат: exampleRoot
Python (lxml) - etree.parse()
from lxml import etree
doc = etree.parse('example.xml')
print(doc.getroot().tag)
Результат: exampleRoot
C# - XmlDocument.Load()
var doc = new System.Xml.XmlDocument();
doc.Load("example.xml");
Console.WriteLine(doc.DocumentElement.Name);
Результат: exampleRoot
Go - encoding/xml Unmarshal/Decoder
type Item struct {
XMLName xml.Name `xml:"root"`
}
var it Item
decoder := xml.NewDecoder(file)
decoder.Decode(&it)
fmt.Println(it.XMLName.Local)
Результат: root
Kotlin - использует Java API (DocumentBuilder) или kotlinx.serialization для других форматов. Отличие: прямой доступ к JVM-библиотекам.
Lua - lxp (LuaExpat) или другие парсеры; API event-driven и менее интегрирован в стандартную библиотеку.
Отличия от Java: в большинстве языков есть как DOM-подобные парсеры, так и потоковые. Java предоставляет богатую стандартную инфраструктуру JAXP, в то время как другие языки полагаются на стандартные или внешние библиотеки с различиями в управлении сущностями, поддержке пространств имен и поведении по умолчанию в отношении безопасности (XXE).
Типичные ошибки при использовании
Частые проблемы и примеры:
1) ParserConfigurationException при создании DocumentBuilder
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://xml.org/sax/features/external-general-entities", true);
DocumentBuilder builder = factory.newDocumentBuilder();
Возможный результат: javax.xml.parsers.ParserConfigurationException: Feature not recognized
Пояснение: некоторые реализации не поддерживают выставленную фичу, либо запрещено в окружении.
2) SAXParseException при некорректном XML
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("broken.xml"));
Возможный результат: org.xml.sax.SAXParseException: The element type "tag" must be terminated by the matching end-tag
3) IOException при проблемах с доступом к ресурсу
Document doc = builder.parse("file:/nonexistent.xml");
Возможный результат: java.io.FileNotFoundException: /nonexistent.xml (No such file or directory)
4) Проблемы с кодировкой при использовании InputStream без указания encoding
InputStream is = new FileInputStream("win1251.xml");
Document doc = builder.parse(is);
Возможный результат: Некорректные символы в тексте при несоответствии кодировок
5) Уязвимость XXE (внешние сущности) при разборе ненадежного XML без отключения внешних сущностей
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("untrusted.xml"));
Результат: Возможная утечка данных через внешний ресурс, если в XML используется DOCTYPE и внешние сущности
Рекомендация: при разборе внешних данных отключать обработку внешних сущностей и включать FEATURE_SECURE_PROCESSING.
Изменения и примечания по версиям
API DocumentBuilder.parse() как таковой стабильна с момента стандартизации JAXP и не претерпевала значительных изменений в сигнатуре. Важные изменения и уточнения относятся к окружению и безопасности:
- Модульность Java (JDK 9+) не изменила поведение parse(), но классы теперь находятся в модуле
java.xml, что влияет на модульные переходы и доступность в модульных приложениях. - Добавлены и стандартизированы фичи безопасности (например,
XMLConstants.FEATURE_SECURE_PROCESSING) и рекомендации по отключению внешних сущностей. Современные реализации и окружения могут по умолчанию ограничивать загрузку внешних DTD или сущностей. - Реализации поставщиков (Xerces, встроенный JDK парсер) обновлялись отдельно, что могло менять поддержку некоторых фич и поведение при обработке крайних случаев XML.
Вывод: явная настройка фабрики и builder-а рекомендуется для предсказуемого поведения в новых версиях JVM.
Расширенные и нестандартные примеры
1) Отключение XXE с кастомным EntityResolver
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
f.setFeature("http://xml.org/sax/features/external-general-entities", false);
f.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder b = f.newDocumentBuilder();
// При желании можно установить EntityResolver, который отвечает пустым вводом
b.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader("")));
Document doc = b.parse(new File("untrusted.xml"));
System.out.println(doc.getDocumentElement().getNodeName());
Результат: При наличии запрещенного DOCTYPE будет исключение или игнорирование внешних сущностей в зависимости от конфигурации
2) Использование ErrorHandler для агрегирования ошибок без прерывания выполнения
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
List errors = new ArrayList<>();
builder.setErrorHandler(new org.xml.sax.ErrorHandler() {
public void warning(org.xml.sax.SAXParseException e) { errors.add("WARN: " + e.getMessage()); }
public void error(org.xml.sax.SAXParseException e) { errors.add("ERROR: " + e.getMessage()); }
public void fatalError(org.xml.sax.SAXParseException e) throws org.xml.sax.SAXException { errors.add("FATAL: " + e.getMessage()); throw e; }
});
try {
Document doc = builder.parse(new File("maybe-invalid.xml"));
} catch (Exception ex) {
// обработка
}
errors.forEach(System.out::println);
Результат: WARN: ... ERROR: ... (в соответствии с содержимым)
3) Модификация DOM и запись результата в файл
Document doc = builder.parse(new File("in.xml"));
Element root = doc.getDocumentElement();
Element newEl = doc.createElement("added");
newEl.setTextContent("value");
root.appendChild(newEl);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource src = new DOMSource(doc);
StreamResult res = new StreamResult(new File("out.xml"));
t.transform(src, res);
System.out.println("Saved to out.xml");
Результат: Saved to out.xml Файл out.xml содержит исходную структуру с добавленным элементом
4) Частичный разбор со совмещением StAX и DOM (экономия памяти)
XMLInputFactory xf = XMLInputFactory.newInstance();
XMLStreamReader xr = xf.createXMLStreamReader(new FileInputStream("big.xml"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
while (xr.hasNext()) {
if (xr.next() == XMLStreamConstants.START_ELEMENT && "item".equals(xr.getLocalName())) {
// создать поддерево для одного -
XMLEventReader er = xf.createFilteredReader(xf.createXMLEventReader(new FileInputStream("big.xml")), ev -> true);
// Здесь можно собрать событие для одного фрагмента и преобразовать в DOM при помощи трансформации
break; // схематично
}
}
Результат: Позволяет обрабатывать поэлементно большие файлы, не загружая весь документ в память
5) Поиск узлов с XPath после parse()
Document doc = builder.parse(new File("books.xml"));
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("/catalog/book[price>35]/title", doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) System.out.println(nodes.item(i).getTextContent());
Результат: Список названий книг, цена которых больше 35
6) Кастомный EntityResolver для локального разрешения DTD
builder.setEntityResolver((publicId, systemId) -> {
if (systemId != null && systemId.endsWith("example.dtd")) {
return new InputSource(new StringReader(""));
}
return null; // дальше по умолчанию
});
Document d = builder.parse(new File("with-doctype.xml"));
Результат: DTD подставлен из кода, внешние обращения не выполнялись
Эти примеры демонстрируют способы безопасного и эффективного применения DocumentBuilder.parse() в различных сценариях: защита, обработка ошибок, интеграция с другими API и экономия памяти.
джава DocumentBuilder.parse function comments
- джава DocumentBuilder.parse - аргументы и возвращаемое значение
- Функция java DocumentBuilder.parse - описание
- DocumentBuilder.parse - примеры
- DocumentBuilder.parse - похожие методы на java
- DocumentBuilder.parse на javascript, c#, python, php
- DocumentBuilder.parse изменения java
- Примеры DocumentBuilder.parse на джава