Отражение img.Xml в объектах Java с использованием JAXB - PullRequest
0 голосов
/ 09 мая 2018

Итак, я перехожу из C # в Unity, где отражение в XML было довольно простым. Я хотел применить тот же процесс в Java для этого к слегка измененной версии уже существующего XML этого типа формата:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="0206.img">
  <imgdir name="02060003">
    <imgdir name="info">
      <canvas name="icon" width="32" height="32">
        <vector name="origin" x="0" y="32" />
      </canvas>
      <canvas name="iconRaw" width="32" height="31">
        <vector name="origin" x="0" y="32" />
      </canvas>
      <int name="price" value="20" />
      <int name="slotMax" value="1000" />
      <int name="incPAD" value="4" />
    </imgdir>
    <imgdir name="bullet">
      <canvas name="0" width="43" height="18">
        <vector name="origin" x="23" y="10" />
        <int name="z" value="0" />
      </canvas>
      <canvas name="1" width="41" height="9">
        <vector name="origin" x="22" y="5" />
        <int name="z" value="0" />
      </canvas>
    </imgdir>
  </imgdir>
  <imgdir name="02060005">
    <imgdir name="info">
      <canvas name="icon" width="26" height="25">
        <vector name="origin" x="-3" y="25" />
        <int name="z" value="0" />
      </canvas>
      <canvas name="iconRaw" width="20" height="18">
        <vector name="origin" x="-6" y="25" />
        <int name="z" value="0" />
      </canvas>
      <int name="slotMax" value="800" />
      <int name="incPAD" value="10" />
      <int name="reqLevel" value="10" />
      <int name="tradeBlock" value="1" />
    </imgdir>
    <imgdir name="bullet">
      <canvas name="0" width="36" height="19">
        <vector name="origin" x="22" y="9" />
        <int name="delay" value="150" />
      </canvas>
      <canvas name="1" width="40" height="22">
        <vector name="origin" x="20" y="11" />
        <int name="delay" value="150" />
      </canvas>
      <canvas name="2" width="43" height="21">
        <vector name="origin" x="21" y="10" />
        <int name="delay" value="150" />
      </canvas>
      <canvas name="3" width="46" height="23">
        <vector name="origin" x="20" y="11" />
        <int name="delay" value="150" />
      </canvas>
    </imgdir>
    <imgdir name="hit">
      <canvas name="0" width="55" height="38">
        <vector name="origin" x="13" y="20" />
        <int name="delay" value="90" />
      </canvas>
      <canvas name="1" width="43" height="55">
        <vector name="origin" x="17" y="29" />
        <int name="delay" value="100" />
      </canvas>
      <canvas name="2" width="51" height="65">
        <vector name="origin" x="26" y="34" />
        <int name="delay" value="100" />
      </canvas>
      <canvas name="3" width="62" height="87">
        <vector name="origin" x="34" y="57" />
        <int name="delay" value="100" />
      </canvas>
    </imgdir>
  </imgdir>

Загвоздка в том, что таких XML-файлов много, и у каждого из них есть разные имена заголовков, например, 0206.img, 0207.img. Каждый из них имеет структуру, очень похожую на предыдущую в этой категории заголовка (начальная цифра определяет, какой тип объекта это демаршалинг).

Я действительно хочу отражать только такие свойства, как цена , slotMax , incPad и игнорировать остальные, если это возможно. Я не знаю, как это сделать, поскольку во всех немаршальных примерах XML намного проще, например

<Employees>
    <Employee>
       <id>1</id>
    </Employee>
    <Employee>
      <id>2</id>
    </Employee>
</Employees>

Там, где вы, вероятно, определите класс, такой как Employees, который содержит List, и Employee можно легко найти. Чтобы уточнить, я знаю, что вы должны установить RootElement для имени верхнего элемента, например, в этом случае 0206.img, но как это может быть динамическим для 0207?

Что касается кода ... Я имею в виду, что кодовая база довольно проста, поскольку она просто определяет структуру, в которую нужно разобрать. Определить эту структуру в отношении приведенного выше XML-кода, для меня сложнее.

1 Ответ

0 голосов
/ 09 мая 2018

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

Если вам нужно всего несколько частей XML, есть более простые способы сделать это. В этом конкретном случае я бы, вероятно, использовал STAX. Нечто подобное:

private static final QName INT_ELEMENT_NAME = new QName("int");

// ...

    XMLInputFactory factory = XMLInputFactory.newInstance();
    XMLStreamReader reader = factory.createXMLStreamReader(is);

    while (reader.hasNext()) {
        if (XMLStreamConstants.START_ELEMENT == reader.next()) {
            if (Objects.equals(INT_ELEMENT_NAME, reader.getName())) {
                String name = reader.getAttributeValue(null, "name");
                String value = reader.getAttributeValue(null, "value");
                System.out.println(name + "=" + value);
            }
        }
    }

Печать имен / значений из всех элементов int. Может быть легко распространен на дальнейшие случаи. Очень быстро, без JAXB, легко работает с большими файлами XML, независимо от их размера.

Есть и другие инструменты. Был один синтаксический анализатор (я не мог вспомнить имя), где вы определяете правила на основе XPath, и анализатор возвращает данные в соответствии с этими правилами. Это также подойдет, но я просто не помню название. Я думаю, что это был какой-то проект Apache.

Обновление : Я наконец нашел его, я говорил о Дайджест . Это позволяет настраивать XPath-подобные правила привязки и создавать объекты для вас. Тем не менее, я бы, вероятно, остановился на решении STAX, если вы не уверены, что получите более сложные правила.

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