Java XStream - Игнорировать тег, который не существует в XML

В настоящее время я использую фрагмент XML, как показано ниже.

<Person>
    <Name>Frank Smith</Name>
    <Id>100023412</Id>
    <DOB>12/05/1954</DOB>
    <LasLogin>01/09/2010</LasLogin>
    <FavOS>Windows</FavOS>      // Wild card that may occasionally appear
</Person>

То, что я застрял, - это при использовании XStream мне нужно уметь игнорировать определенные теги, которые появляются (в случае выше "FavOS" ) Эти теги могут быть неизвестны или изменены в будущем. Есть ли способ игнорировать все теги, которые не соответствуют тому, что в настоящее время реализовано?

(Использование XStream 1.3.1)

Ответ 1

Как мне потребовалось более 15 минут, чтобы найти этот ответ, я подумал, что отправлю его.

XStream xstream = new XStream(new DomDriver()) {
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    public boolean shouldSerializeMember(Class definedIn, String fieldName) {
                        try {
                            return definedIn != Object.class || realClass(fieldName) != null;
                        } catch(CannotResolveClassException cnrce) {
                            return false;
                        }
                    }
                };
            }
        };

Кажется, что пропускают элементы xml, которые не находятся в ваших объектах.

Ответ 2

XStream 1.4.5 поддерживает работу с тегами, которые не реализованы. Используйте ignoreUnknownElements для тегов, которые еще не реализованы или были удалены, и вы имеете дело со старым xml. Вы также можете указать, какой конкретный тег вы хотите игнорировать.

Ответ 3

Прежде всего, спасибо за обмен этим ответом. Это было очень полезно. Однако упомянутый выше код имеет проблемы. В нем нет аннотаций @Override, которые необходимы для использования этого фрагмента кода. Вот обновленный код, который работает:

    XStream xstream = new XStream(new StaxDriver()) {
          @Override
          protected MapperWrapper wrapMapper(MapperWrapper next) {
            return new MapperWrapper(next) {
              @Override
              public boolean shouldSerializeMember(Class definedIn,
                      String fieldName) {
                if (definedIn == Object.class) {
                  return false;
                }
                return super.shouldSerializeMember(definedIn, fieldName);
              }
            };
          }
        };

Ответ 4

Из x-stream FAQ:

Как XStream справляется с новыми версии классов?

  • Если в класс добавлено новое поле, десериализация старой версии оставит поле неинициализированным.
  • Если поле удалено из класса, десериализация старой версии, содержащей это поле, вызовет исключение. Оставляя поле на месте, но объявляя его временным, избегает исключения, но XStream не будет пытаться десериализовать его.
  • ...
  • реализовать пользовательский сопоставитель для автоматического игнорирования неизвестных полей (см. приемочный тест CustomMapperTest.testCanBeUsedToOmitUnexpectedElements())

Ответ 5

Так как XStream 1.4.5 выдает объявление маршаллера, достаточно использовать метод ignoreEnknownElements():

XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.getXStream().ignoreUnknownElements();
...

игнорировать ненужные элементы.

Ответ 6

Я попросил точно такую ​​же проблему.

Как я могу заставить XStreamMarshaller пропускать неизвестную привязку?

И я получил комментарий, связанный с этим сообщением.

Я решил свою проблему, расширив XStreamMarshaller.

public class ExtendedXStreamMarshaller extends XStreamMarshaller {

    @Override
    protected void configureXStream(final XStream xstream) {
        super.configureXStream(xstream);
        xstream.ignoreUnknownElements(); // will it blend?
    }
}