Как расширить XMLStreamReader?

http://docs.oracle.com/javaee/5/api/javax/xml/stream/XMLStreamReader.html

Я хочу расширить XMLStreamReader, но это интерфейс.

Я хочу сделать что-то вроде:

public class GraphDataStreamReader extends XMLStreamReader{

  public GraphDataStreamReader(){
    super();
  }

  public void nextStartElement() throws XMLStreamException {
    do {
      super.next();   
    } while (!super.isStartElement());
  }
}

Другой класс:

XMLInputFactory factory = XMLInputFactory.newInstance();
GraphDataStreamReader streamReader = (GraphDataStreamReader) factory.createXMLStreamReader(new FileReader(xmlFile)); //returns XMLStreamReader
streamReader.next(); //method from XMLStreamReader
streamReader.nextStartElement(); //method from GraphDataStreamReader

Это возможно? Если да, то как?


person Spenhouet    schedule 17.06.2014    source источник
comment
использовать инструменты вместо расширений   -  person CocoNess    schedule 17.06.2014
comment
Если у вас Java 6 или выше, вы можете расширить StreamReaderDelegate.   -  person McDowell    schedule 17.06.2014
comment
@McDowell: Похоже, это то, что я искал. Но есть ошибка в литье. Не могли бы вы дать ответ на вопрос?   -  person Spenhouet    schedule 17.06.2014
comment
Обычно вы реализуете интерфейс (с классом). Вы можете расширить интерфейс (но только другим, дочерним интерфейсом. Никогда классом). И в вашем случае вы, вероятно, захотите найти (или написать) класс, который уже реализует XmlStreamReader... и затем расширить этот класс. Google для java реализует XmlStreamReader, и вы увидите, что StreamReaderDelegate является одним из таких классов.   -  person FoggyDay    schedule 18.06.2014


Ответы (3)


Вот как расширить StreamReaderDelegate:

class GraphDataStreamReader extends StreamReaderDelegate {
  public GraphDataStreamReader(XMLStreamReader reader) {
    super(reader);
  }

  public void nextStartElement() throws XMLStreamException {
    do {
      super.next();
    } while (!super.isStartElement());
  }
}

XMLInputFactory factory = XMLInputFactory.newInstance();
GraphDataStreamReader streamReader = new GraphDataStreamReader(
                                 factory.createXMLStreamReader(fileInputStream));
streamReader.next();
streamReader.nextStartElement();
person McDowell    schedule 18.06.2014
comment
Я пробовал это так, но новый streamReader равен нулю. - person Spenhouet; 18.06.2014
comment
streamReader никогда не может быть нулевым в этом коде - ему присваивается новый объект в строке объявления. - person McDowell; 18.06.2014
comment
Вы правы ;) У меня была ошибка в коде... Спасибо, знаю, что это работает :) - person Spenhouet; 18.06.2014

Вы можете попробовать шаблон делегирования, например:

public class GraphDataStreamReader implements XMLStreamReader {

    private XMLStreamReader delegate;

    public GraphDataStreamReader (XMLStreamReader delegate) {
        this.delegate = delegate;
    }

    @Override
    public void close() throws XMLStreamException {
        delegate.close();
    }

    ... similar for other methods of XMLStreamReader ...

    ... then add your own methods ...
}
person Manfred Michels    schedule 17.06.2014
comment
Эй, Манфрид, спасибо за помощь. Я не думаю, что это то, что я ищу. К тому же уже есть класс делегата (как писал Макдауэлл) -> StreamReaderDelegate - person Spenhouet; 17.06.2014

Теперь я решил это (после многих попыток).

Расширенный XMLStreamReader с собственными методами:

public class GraphDataStreamReader extends XMLStreamReaderImpl {
  public GraphDataStreamReader(InputStream arg0, PropertyManager arg1) throws XMLStreamException {
    super(arg0, arg1);
  }
  public boolean nextStartElement() throws XMLStreamException {
    ....
  }
}

Класс, использующий GraphDataStreamReader:

public class GraphDataParser {
  private GraphDataStreamReader graphSR;

  private GraphDataParser(String xmlFile) throws FileNotFoundException, XMLStreamException {
    FileInputStream inStream = new FileInputStream(new File(xmlFile));
    graphSR = new GraphDataStreamReader(inStream, new PropertyManager(1));
  }
}

Спасибо за все ваши идеи. Большинство кредитов Макдауэллу. Из-за его поста я продолжаю пытаться. Я надеюсь, что этот вопрос все еще используется для кого-то еще.

person Spenhouet    schedule 17.06.2014
comment
Это расширение com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl? Это не очень хорошая идея. - person McDowell; 18.06.2014
comment
Да, почему? Работает отлично. - person Spenhouet; 18.06.2014
comment
Это внутренний API; если вы обновите свою среду выполнения Java или запустите другую реализацию, этого класса может не быть. - person McDowell; 18.06.2014
comment
Я этого не знал. Как я увижу, что это внутренний API? - person Spenhouet; 18.06.2014
comment
Он не задокументирован в стандартном Java API. Вы также можете использовать инструмент jdeps с параметр jdkinternals. Слово internal в названии пакета также является подсказкой. - person McDowell; 18.06.2014