Есть ли какие-либо преимущества использования таблицы стилей XSLT по сравнению с ручным анализом XML-файла с использованием анализатора DOM - PullRequest
4 голосов
/ 21 февраля 2011

Для одного из наших приложений я написал утилиту, которая использует анализатор Java DOM. Он в основном берет файл XML, анализирует его и затем обрабатывает данные, используя один из следующих методов, чтобы фактически извлечь данные.

getElementByTagName()
getElementAtIndex()
getFirstChild()
getNextSibling()
getTextContent()

Теперь я должен сделать то же самое, но мне интересно, будет ли лучше использовать таблицу стилей XSLT. Организация, которая отправляет нам XML-файл, постоянно меняет свою схему, что означает, что мы должны изменить наш код, чтобы обслужить эти изменения схемы. Я не очень знаком с процессом XSLT, поэтому я пытаюсь выяснить, лучше ли мне использовать таблицы стилей XSLT, а не «ручной анализ».

Причина, по которой таблицы стилей XSLT выглядят привлекательно, заключается в том, что я думаю, что если схема XML-файла изменится, мне нужно будет только изменить таблицу стилей? Это правильно?

Еще одна вещь, которую я хотел бы знать, это то, какой из двух (XSLT-преобразователь или DOM-анализатор) лучше по производительности. Для ручного варианта я просто использую парсер DOM для разбора XML-файла. Как преобразователь XSLT на самом деле анализирует файл? Включает ли это дополнительные издержки по сравнению с анализом вручную XML-файла? Причина, по которой я спрашиваю, заключается в том, что производительность важна из-за характера данных, которые я буду обрабатывать.

Любой совет?

Спасибо

Редактировать

По сути, я сейчас занимаюсь синтаксическим анализом файла xml и обрабатываю значения в некоторых элементах xml. Я не преобразовываю XML-файл в любой другой формат. Я просто извлекаю некоторое значение, извлекаю строку из базы данных Oracle и сохраняю новую строку в другую таблицу. Анализируемый xml-файл содержит только справочные значения, которые я использую для извлечения некоторых данных из базы данных.

xslt не подходит в этом сценарии? Есть ли лучший подход, который я могу использовать, чтобы избежать изменений кода при изменении схемы?

Редактировать 2

Извините за недостаточную ясность в отношении того, что я делаю с данными XML. В основном это XML-файл, который содержит некоторую информацию. Я извлекаю эту информацию из файла XML и использую ее для получения дополнительной информации из локальной базы данных. Данные в XML-файле больше похожи на справочные ключи для данных, которые мне нужны в базе данных. Затем я беру содержимое, извлеченное из файла XML, плюс содержимое, извлеченное из базы данных, используя определенный ключ из файла XML, и сохраняю эти данные в другой таблице базы данных.

Проблема, с которой я столкнулся, заключается в том, что я знаю, как написать синтаксический анализатор DOM для извлечения необходимой мне информации из файла XML, но мне было интересно, было ли лучше использовать таблицу стилей XSLT, поскольку мне не пришлось бы менять код, если схема меняется.

Чтение ответов ниже звучит так, как будто XSLT используется только для преобразования и передачи XML-файла в другой XML-файл или какой-либо другой формат. Учитывая, что я не собираюсь преобразовывать XML-файл, вероятно, нет необходимости добавлять дополнительные накладные расходы при разборе таблицы стилей XSLT, а также XML-файла.

Ответы [ 4 ]

4 голосов
/ 21 февраля 2011

Преобразование документов XML в другие форматы является причиной XSLT.Вы можете использовать XSLT для вывода HTML, JSON, другого XML-документа или чего-либо еще, что вам нужно.Вы не указываете, какой вывод вы хотите.Если вы просто захватываете содержимое нескольких элементов, то, возможно, вам не захочется беспокоиться о XSLT.XSLT предлагает элегантное решение.Это в первую очередь потому, что XSLT понимает структуру документа, над которым он работает.Его модель обработки - это обход дерева и сопоставление с шаблоном, что, по сути, вы и делаете в Java вручную.

Вы можете использовать XSLT для преобразования ваших исходных данных в представление по вашему выбору.Ваш код всегда будет работать с этой структурой.Затем, когда организация, с которой вы работаете, меняет схему, вам нужно всего лишь изменить свой XSLT, чтобы преобразовать новый XML в ваш пользовательский формат.Ни один из вашего другого кода не нуждается в изменении.Почему ваша бизнес-логика должна заботиться о формате исходных данных?

3 голосов
/ 22 февраля 2011

Вы правы, что модель обработки XSLT, основанная на основанном на правилах подходе, основанном на событиях, делает ваш код более устойчивым к изменениям в схеме.

Поскольку это модель обработки, отличная от процедурного / навигационного подхода, которыйвы используете с DOM, есть кривая обучения и ознакомления, что некоторые люди расстраивают;если вы хотите пойти по этому пути, наберитесь терпения, потому что пройдет некоторое время, прежде чем идеи вступят в действие.Как только вы окажетесь там, это будет намного проще, чем программирование DOM.

Производительность хорошего XSLT-процессора будет достаточно для ваших нужд.Конечно, можно написать очень неэффективный код, как на любом языке, но я редко видел систему, где XSLT был узким местом.Очень часто синтаксический анализ XML занимает больше времени, чем обработка XSLT (и это та же стоимость, что и с DOM, JAXB или чем-то еще.)

Как уже говорили другие, многое зависит от того, что вы хотите сделать с XMLданные, которые вы на самом деле не объяснили.

1 голос
/ 21 февраля 2011

Я думаю, что вам нужно выражение XPath. Вы можете настроить это выражение в некотором файле свойств или в любом другом месте, которое вы используете для получения параметров настройки.

Таким образом, вы просто меняете выражение XPath всякий раз, когда ваш клиент скрывает информацию, которую вы используете, в другом месте.

По сути, XSLT - это перебор, вам просто нужно выражение XPath. Одно выражение XPath позволит вам найти каждое значение, которое вам нужно.

Обновление

Поскольку мы сейчас говорим о JDK 1.4 , я включил ниже 3 различных способа извлечения текста в файл XML с использованием XPath. (как можно проще, я не боюсь пуха для защиты NPE; -)

Начиная с самого последнего.

0. Сначала образец XML-файла конфигурации

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <param id="MaxThread" desc="MaxThread"        type="int">250</param>
    <param id="rTmo"      desc="RespTimeout (ms)" type="int">5000</param>
</config>

1. Использование JAXP 1.3 стандартной части Java SE 5.0

import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.Document;

public class TestXPath {

    private static final String CFG_FILE = "test.xml" ;
    private static final String XPATH_FOR_PRM_MaxThread = "/config/param[@id='MaxThread']/text()";
    public static void main(String[] args) {

        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        docFactory.setNamespaceAware(true);
        DocumentBuilder builder;
        try {
            builder = docFactory.newDocumentBuilder();
            Document doc = builder.parse(CFG_FILE);
            XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH_FOR_PRM_MaxThread);
            Object result = expr.evaluate(doc, XPathConstants.NUMBER);
            if ( result instanceof Double ) {
                System.out.println( ((Double)result).intValue() );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. Использование JAXP 1.2 стандартной части Java SE 1.4-2

import javax.xml.parsers.*;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.*;

public class TestXPath {

    private static final String CFG_FILE = "test.xml" ;
    private static final String XPATH_FOR_PRM_MaxThread = "/config/param[@id='MaxThread']/text()";

    public static void main(String[] args) {

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            docFactory.setNamespaceAware(true);
            DocumentBuilder builder = docFactory.newDocumentBuilder();
            Document doc = builder.parse(CFG_FILE);
            Node param = XPathAPI.selectSingleNode( doc, XPATH_FOR_PRM_MaxThread );
            if ( param instanceof Text ) {
                System.out.println( Integer.decode(((Text)(param)).getNodeValue() ) ); 
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. Использование JAXP 1.1 стандартной части Java SE 1.4 + jdom + jaxen

Вам необходимо добавить эти 2 баночки (доступно на www.jdom.org - бинарные файлы, в комплекте jaxen).

import java.io.File;
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

public class TestXPath {

    private static final String CFG_FILE = "test.xml" ;
    private static final String XPATH_FOR_PRM_MaxThread = "/config/param[@id='MaxThread']/text()";

    public static void main(String[] args) {
        try {
            SAXBuilder sxb = new SAXBuilder();
            Document doc = sxb.build(new File(CFG_FILE));
            Element root = doc.getRootElement();
            XPath xpath = XPath.newInstance(XPATH_FOR_PRM_MaxThread);
            Text param = (Text) xpath.selectSingleNode(root);
            Integer maxThread = Integer.decode( param.getText() );
            System.out.println( maxThread );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
0 голосов
/ 24 февраля 2011

Поскольку производительность важна, я бы предложил для этого использовать SAX-парсер. JAXB даст вам примерно такую ​​же производительность, что и DOM Parsing PLUS, это будет намного проще и удобнее в обслуживании. Обработка изменений в схеме также не должна сильно повлиять на вас, если вы используете JAXB, просто получите новую схему и заново создайте классы. Если у вас есть мост между JAXB и логикой вашего домена, то изменения могут быть поглощены этим уровнем, не беспокоясь о XML. Я предпочитаю рассматривать XML как просто сообщение, которое используется на уровне обмена сообщениями. Весь код приложения должен быть независим от схемы XML.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...