StAX XML весь контент между двумя обязательными тегами

Начав изучать StAX с помощью XMLStreamReader, я столкнулся с проблемой. Как я могу получить ВСЕ содержимое между тегами в виде текста? Я имею в виду, что я знаю имя нужного тега, и когда я его нахожу, я должен перейти к закрывающему тегу, и все, что я нашел между ними, я должен добавить в какую-то строку. Например, у нас есть что-то вроде

<rootTag>
...    
    <someTag>
        Some text content and other tags here…
    </someTag >
    <tagINeed>
        <someinternalTag1>
            <someinternalTag11>
                Some text content..
            </someinternalTag11>
            ...
        </someinternalTag1>
        <someinternalTag2>
            Something here
        </someinternalTag2>
    </tagINeed>
...
    <somethingAnother>
...
    </somethingAnother >
...
</rootTag>    

Итак, мне нужно получить свою строку как

        <someinternalTag1>
            <someinternalTag11>
                Some text content..
            </someinternalTag11>
            ...
        </someinternalTag1>
        <someinternalTag2>
            Something here
        </someinternalTag2>

Как я могу это получить? Может быть, я должен найти начальное и конечное смещения нужного блока в исходном xml и дать подстроку после разбора?


person Den Doeson    schedule 27.12.2012    source источник


Ответы (3)


Пытаться

    StringWriter sw = new StringWriter();
    XMLOutputFactory of = XMLOutputFactory.newInstance(); 
    XMLEventWriter xw = null;
    XMLInputFactory f = XMLInputFactory.newInstance();
    XMLEventReader xr = f.createXMLEventReader(new FileInputStream("test.xml"));
    while (xr.hasNext()) {
        XMLEvent e = xr.nextEvent();
        if (e.isStartElement()
                && ((StartElement) e).getName().getLocalPart().equals("tagINeed")) {
            xw = of.createXMLEventWriter(sw);
        } else if (e.isEndElement()
                && ((EndElement) e).getName().getLocalPart().equals("tagINeed")) {
            break;
        } else if (xw != null) {
            xw.add(e);
        }
    }
    xw.close();
    System.out.println(sw);

отпечатки

    <someinternalTag1>
        <someinternalTag11>
            Some text content..
        </someinternalTag11>
    </someinternalTag1>
    <someinternalTag2>
        Something here
    </someinternalTag2>

Обновление:

Если вам нужна строка XML, мы можем написать так:

        if (e.isStartElement() &&
                ((StartElement) e).getName().getLocalPart().equals("tagINeed")){
            xw = of.createXMLEventWriter(sw);
            xw.add(e);
        } else if (e.isEndElement() &&
                ((EndElement) e).getName().getLocalPart().equals("tagINeed")){
            xw.add(e);
            break;
        } else if (xw != null) {
            xw.add(e);
        }
person Evgeniy Dorofeev    schedule 27.12.2012
comment
Но он выводит [Событие Stax # 4] [Событие Stax # 1] [Событие Stax # 4] [Событие Stax # 1] [Событие Stax # 4] [Событие Stax # 2] [Событие Stax # 4] [Событие Stax # 2] ][Событие Stax #4][Событие Stax #1][Событие Stax #4][Событие Stax #2][Событие Stax #4] - person Den Doeson; 28.12.2012
comment
Что ж, этот вывод реален. Мой StAX - это внутренний Java 7 com.sun.xml.internal.stream.XMLInputFactoryImpl. Какой у вас StAX? - person Evgeniy Dorofeev; 28.12.2012
comment
В любом случае, попробуйте мою обновленную версию, она не зависит от реализации StAX. - person Evgeniy Dorofeev; 28.12.2012
comment
e- - это просто тип события. Моя проблема заключается в том, как получить содержимое в текущей позиции в виде текста без проверки типа. Чтобы не делать что-то вроде if(e == XMLStreamConstants.START_ELEMENT){ System.out.println(‹ + reader.getLocalName() + ›); } else if(e == XMLStreamConstants.END_ELEMENT){ System.out.println(‹/ + reader.getLocalName() + ›); } else if(e == XMLStreamConstants.CHARACTERS){ System.out.println(reader.getText()); } - person Den Doeson; 28.12.2012
comment
извините, не понимаю .. я должен импортировать XMLInputFactory из com.sun.xml.internal.stream? Но такого класса в этом пакете нет... Могу я попросить вас опубликовать здесь полный текст программы, с импортной частью? - person Den Doeson; 28.12.2012
comment
Просто попробуйте мою последнюю версию, она исправлена, чтобы не зависеть от реализации StAX. - person Evgeniy Dorofeev; 28.12.2012
comment
Что касается внедрения StAX: когда вы вызываете javax.xml.stream.XMLInputFactory.newInstance(), XMLInputFactory ищет реальную реализацию, и если на пути к классу нет провайдеров, он берет значение по умолчанию из rt.jar. - person Evgeniy Dorofeev; 28.12.2012
comment
спасибо + 1. но это не работает, если есть внутренний тег с таким же именем. Я добавил счетчик. Смотри ниже. - person guillaume girod-vitouchkina; 06.08.2017

Решение Е. Дорофеева хорошее, но не работает, если есть внутренний тег с таким же именем. Я добавил счетчик.

String fichier="test_stax_2.txt";

String tag="tagINeed";
int count=0;

StringWriter sw = new StringWriter();
XMLOutputFactory of = XMLOutputFactory.newInstance(); 
XMLEventWriter xw = null;
XMLInputFactory f = XMLInputFactory.newInstance();
XMLEventReader xr = f.createXMLEventReader(new FileInputStream(fichier));

while (xr.hasNext())
    {
    XMLEvent e = xr.nextEvent();
    if (e.isStartElement()
            && ((StartElement) e).getName().getLocalPart().equals(tag))
        {
        if (count==0)
            xw = of.createXMLEventWriter(sw);
        else
            xw.add(e);
        count++;
        } 

    else if (e.isEndElement()
            && ((EndElement) e).getName().getLocalPart().equals(tag))
        {
        count --;
        if (count==0)
            break;
        else
            xw.add(e);
        } 
        else if (xw != null) 
        {
        xw.add(e);
        }
}
if (xw!=null)
   xw.close();

System.out.println(sw);
person guillaume girod-vitouchkina    schedule 06.08.2017

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

Transformer t=TransformerFactory.newInstance().newTransformer();
StringWriter sw=new StringWriter();         
StreamResult result=new StreamResult(sw);//holds the result of a transformation
DOMSource d=new DOMSource(XMLdoc);//your XML document
t.transform(d, result);
String xmlstring=sw.toString();

вы можете использовать xmlstring для получения желаемого результата.

person Shurmajee    schedule 27.12.2012