Внешний связывающий файл JAXB xpath для последовательности в сложном типе - PullRequest
0 голосов
/ 04 мая 2018

У меня вопрос по поводу выражения node xpath в <jxb:bindings\>:

У меня есть тип, который я использую несколько раз в xsd, указанный в его собственном xsd:

common.xsd:

<?xml version="1.0" encoding="UTF-8"?>                                                                                                                                                                                                                                           
<xsd:schema                                                                                                                 
  targetNamespace="http://www.example.com/xsd/common"                                                                       
  xmlns="http://www.example.com/xsd/common"                                                                                 
  xmlns:tns="http://www.example.com/xsd/common"                                                                             
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"                                                                              
  elementFormDefault="qualified">                                                                                           

  <xsd:complexType name="Parameter">
   <xsd:simpleContent>
     <xsd:extension base="xsd:string">
        <xsd:attribute name="key" type="xsd:string" use="required" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
</xsd:schema>

включено несколько раз в другую схему:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
  targetNamespace="http://www.example.com/xsd/example"
  xmlns="http://www.example.com/xsd/example"
  xmlns:tns="http://www.example.com/xsd/example"
  xmlns:c="http://www.example.com/xsd/common"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">

<xsd:element name="example" type="example" />

<xsd:complexType name="example">
  <xsd:all>
    <xsd:element name="working" type="working" />
    <xsd:element name="notworking" type="notworking" />
  </xsd:all>
</xsd:complexType>

<xsd:complexType name="working">
  <xsd:all>
    <xsd:element name="Parameters">
      <xsd:sequence>
        <xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
      </xsd:sequence>
    </xsd:element>
  </xsd:all>
</xsd:complexType>

<xsd:complexType name="notworking">
  <xsd:sequence>
    <xsd:element name="Parameter" type="c:Parameter" maxOccurs="unbounded" />
  </xsd:sequence>
  <xsd:attribute name="anAttribute" type="xsd:token" />
</xsd:complexType>

</xsd:schema>

для связывания с jaxb, у меня есть класс ParameterMap:

package com.example.common.xml.model;

import java.util.HashMap;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.example.common.xml.binding.ParameterAdapter;

@XmlJavaTypeAdapter(ParameterAdapter.class)
public class ParameterMap extends HashMap<String, String> {}

а также класс адаптера:

package com.example.common.xml.binding;

import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import com.example.common.xml.model.ObjectFactory;
import com.example.common.xml.model.Parameter;
import com.example.common.xml.model.ParameterMap;

public class ParameterAdapter extends XmlAdapter<List<Parameter>, ParameterMap> {
  public ParameterMap unmarshal(List<Parameter> params) {
    ParameterMap map = new ParameterMap();
    for (Parameter p : params) {
      map.put(p.getKey(), p.getValue());
    }
    return map;
  }

  public List<Parameter> marshal(ParameterMap map) {
    List<Parameter> params = new ArrayList<>();
    ObjectFactory of = new ObjectFactory();
    for (Map.Entry<String, String> e : map.entrySet()) {
      Parameter p = of.createParameter();
      p.setKey(e.getKey());
      p.setValue(e.getValue());
      params.add(p);
    }
    return params;
  }
}

и, конечно, файлы привязок, чтобы классы Parameter и ObjectFactory были сгенерированы в правильный пакет. Файл привязок для примера пространства имен выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="1.0"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  jxb:extensionBindingPrefixes="xjc">

  <jxb:bindings schemaLocation="../pathTo/example.xsd" node="/xs:schema">

    <jxb:bindings node="//xs:complexType[@name='working']//xs:element[@name='Parameters']">
      <jxb:class name="com.example.common.xml.model.ParameterMap" />
    </jxb:bindings>

    <jxb:bindings node="//xs:complexType[@name='notworking']//xs:element[@name='Parameter']">
      <jxb:class name="com.example.common.xml.model.ParameterMap" />
    </jxb:bindings>

  </jxb:bindings>

</jxb:bindings>

Как видно из именования, привязка для дочернего элемента working генерируется правильно, а привязка для notworking приводит к созданию сгенерированного члена класса

@XmlElement(name = "Parameter")
protected List<ParameterMap> parameter;

то, на что я хотел бы выглядеть, было бы так же, как в working:

@XmlElement(name="Parameters")
protected ParameterMap parameters;

«Параметры» меняют не «Параметры», а тип неверный - любая помощь в том, как этого добиться, приветствуется.

Я также уже пытался применить привязку notworking к последовательности (через node="//xs:complexType[@name='notworking']/xs:sequence"), но это просто игнорируется. Если я попытаюсь применить его непосредственно к notworking complexType, это приведет к ошибке разбора.

1 Ответ

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

Проблема не в XPath, по-видимому, работает нормально.

Проблема в том, что этот подход не будет работать. jaxb:class не преобразует свойство вашей коллекции в одно свойство, оно только настраивает тип элемента коллекции.

Вы можете написать для этого плагин XJC, но это несколько сложно.

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