- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个应用程序,该应用程序将集成到一个 API,该 API 具有返回 XSD 支持的 XML 的端点。我的应用程序最初必须针对两个不同的版本(也许在未来的版本中会更多),并且这不必是动态的。当您启动应用程序时,用户必须告诉应用程序要支持哪个 API 主要版本。 XSD 不受我的控制,我不想编辑它们。
XSD 生成同名的类,我已经在那里遇到了问题。我无法将 XJC 生成的两个 ObjectFactory
类加载到 JAXBContext 中。我现在的解决方案是 JAXBContexts 的映射:
private static Map<Integer, Pair<Class<?>, JAXBContext>> contexts = new HashMap<>();
static {
try {
contexts.put(4, Pair.of(com.api.v4_2_0.ObjectFactory.class, JAXBContext.newInstance(com.api.v4_2_0.ObjectFactory.class)));
contexts.put(3, Pair.of(com.api.v3_9_4.ObjectFactory.class, JAXBContext.newInstance(com.api.v3_9_4.ObjectFactory.class)));
} catch (JAXBException e) {
LOGGER.error("Failed to initialize JAXBContext", e);
}
}
该对用于了解 JAXBContext 基于哪个类,因为我无法在运行时恢复它。然后,为了序列化一个对象,我使用了很多神奇的反射,这些反射有效但感觉不正确:
public static String objectToString(final Object object, final Integer majorVersion) {
try {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
getMarshallerForMajorVersion(majorVersion).marshal(createJaxbElementFromObject(object, getObjectFactoryForMajorVersion(majorVersion)), os);
return os.toString(UTF_8);
} catch (JAXBException e) {
throw SesameException.from("Failed to serialize object", e);
}
}
private static Marshaller getMarshallerForMajorVersion(final Integer majorVersion) throws JAXBException {
return getContextForMajorVersion(majorVersion).getRight().createMarshaller();
}
private static Class<?> getObjectFactoryForMajorVersion(final Integer majorVersion) {
return getContextForMajorVersion(majorVersion).getLeft();
}
private static Pair<Class<?>, JAXBContext> getContextForMajorVersion(final Integer majorVersion) {
if (contexts.containsKey(majorVersion)) {
return contexts.get(majorVersion);
}
throw illegalArgument("No JAXBContext for API with major version %d", majorVersion);
}
private static JAXBElement<?> createJaxbElementFromObject(final Object object, final Class<?> objectFactory) {
try {
LOGGER.info("Attempting to find a JAXBElement producer for class {}", object.getClass());
final Method method = findElementMethodInObjectFactory(object, objectFactory);
return (JAXBElement<?>) method.invoke(objectFactory.getConstructor().newInstance(), object);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException e) {
throw illegalArgument("Failed to construct JAXBElement for class %s", object.getClass().getName());
}
}
private static Method findElementMethodInObjectFactory(final Object object, final Class<?> left) {
return Arrays.stream(left.getMethods())
.filter(m -> m.getReturnType().equals(JAXBElement.class))
.filter(m -> m.getName().endsWith(object.getClass().getSimpleName()))
.findFirst()
.orElseThrow(() -> illegalArgument("Failed to find JAXBElement constructor for class %s", object.getClass().getName()));
}
这工作正常,但感觉很脆弱。
问题
更糟糕的是必须使用泛型将 XML 反序列化为对象:
public static <T> T stringToObject(final String xml, final Class<T> toClass, final Integer majorVersion) {
try {
final Unmarshaller unmarshaller = getUnmarshallerForVersion(majorVersion);
final JAXBElement<T> unmarshalledElement = (JAXBElement<T>) unmarshaller.unmarshal(new StringReader(xml));
return toClass.cast(unmarshalledElement.getValue());
} catch (JAXBException e) {
throw SesameException.from(format("Failed to deserialize XML into %s", toClass.getCanonicalName()), e);
}
}
// And calling this from another class
private com.api.v4_2_0.SomeClass.class toSomeClass(final HttpResponse<String> response) {
return XmlUtil.stringToObject(response.body(), com.api.v4_2_0.SomeClass.class, apiMajorVersion); // <--- I can't beforehand use this package since major version might be 3.
}
现在(据我所知)我无法使用泛型并根据使用的 API 主要版本将其映射到正确包中的正确类。
我还尝试使用抽象基类,并为每个版本提供一个ObjectFactory
,但这仍然给我带来了问题部分中描述的问题。我不知道如何返回该类的正确版本:
private com.api.v4_2_0.SomeClass.class toSomeClass(final HttpResponse<String> response) {
return version4XmlUtil.stringToObject(response.body(), com.api.v4_2_0.SomeClass.class); // <--- I can't beforehand use this package since major version might be 3.
}
如何构建我的代码来解决这个问题?哪些模式有用?我完全走错路了吗?
最佳答案
EclipseLink JAXB (MOXy) 的 @XmlPath 和外部绑定(bind)文件扩展可以提供帮助。
我在下面引用的博客将单个对象模型映射到两个不同的 XML 模式。它通过使用标准 JAXB 和 MOXy 扩展注释的组合来映射第一个 API 来实现此目的。
package blog.weather;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name="xml_api_reply")
@XmlType(propOrder={"location", "currentCondition", "currentTemperature", "forecast"})
@XmlAccessorType(XmlAccessType.FIELD)
public class WeatherReport {
@XmlPath("weather/forecast_information/city/@data")
private String location;
@XmlPath("weather/current_conditions/temp_f/@data")
private int currentTemperature;
@XmlPath("weather/current_conditions/condition/@data")
private String currentCondition;
@XmlPath("weather/forecast_conditions")
private List<Forecast> forecast;
}
然后...
package blog.weather;
import org.eclipse.persistence.oxm.annotations.XmlPath;
public class Forecast {
@XmlPath("day_of_week/@data")
private String dayOfTheWeek;
@XmlPath("low/@data")
private int low;
@XmlPath("high/@data")
private int high;
@XmlPath("condition/@data")
private String condition;
}
您无法通过注释创建到对象模型的辅助映射集,因此其他映射可以利用 MOXy 的 XML 元数据,从而覆盖第二个 API。
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="blog.weather"
xml-mapping-metadata-complete="true">
<xml-schema element-form-default="QUALIFIED">
<xml-ns prefix="yweather" namespace-uri="http://xml.weather.yahoo.com/ns/rss/1.0"/>
</xml-schema>
<java-types>
<java-type name="WeatherReport" xml-accessor-type="FIELD">
<xml-root-element name="rss"/>
<xml-type prop-order="location currentTemperature currentCondition forecast"/>
<java-attributes>
<xml-attribute java-attribute="location" xml-path="channel/yweather:location/@city"/>
<xml-attribute java-attribute="currentTemperature" name="channel/item/yweather:condition/@temp"/>
<xml-attribute java-attribute="currentCondition" name="channel/item/yweather:condition/@text"/>
<xml-element java-attribute="forecast" name="channel/item/yweather:forecast"/>
</java-attributes>
</java-type>
<java-type name="Forecast" xml-accessor-type="FIELD">
<java-attributes>
<xml-attribute java-attribute="dayOfTheWeek" name="day"/>
<xml-attribute java-attribute="low"/>
<xml-attribute java-attribute="high"/>
<xml-attribute java-attribute="condition" name="text"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
默认行为是 MOXy 的映射文档用于增强模型上指定的任何注释。不过,根据您设置 xml-mapping-metadata-complete
标志的方式,XML 元数据可以完全替换,或者简单地增强(默认),注释提供的元数据。
试穿一下尺码,然后告诉我您的想法:
Mapping Objects to Multiple XML Schemas Using EclipseLink MOXy http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html
关于java - 处理 XSD 生成的类的多个版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59421860/
我知道我以前在某个地方看到过这个,但我再也找不到它了。我需要一个从另一个 xsd 中调用 xsd 文件的示例。这在生成大量 xml 文件的情况下非常有用,但在这些 xml 文件之间存在大量公共(pub
有人知道供应商中立的 XSD 来描述关系数据库模式吗?我们的系统需要获取有关数据库结构的信息: 表 列和类型 主键和外键约束 索引 等 以独立于供应商的方式并将其存储在 XML 文件中以供以后处理。
我在 XSD 中使用 gml (3.1.1) XSD 作为我的应用程序。我想下载版本 3.1.1 中的所有 gml XSD,例如 zip 文件。换句话说:基本 xsd 是 here我想用 zip 文件
我想要一个 XSD 来验证包含具有许多别名但每个别名具有不同值的文件元素的 XML。 这是我的 XML: Document1
我看到一个 xml 架构 ( EPP ) 将 xsd:choice 与一个元素一起使用,即使我们可以使用 xsd:enumeration 代替:
我目前工作的公司将架构或契约(Contract)版本编入根节点。例如, ... 我正在寻找人们对这种设计方法的意见,因为我不相信它是合理的。例如,它要求所有使用此模式作为消息传递契约的服务都能够发
我在处理 Web 服务响应时遇到了 Apache CXF 解析错误。归结为一个空元素被返回: 元素定义如下: 现在我在 CXF 邮件列表上看到了 empty value is not allowe
XSD 可以为比较两个元素添加约束吗? 假设我在 DataRangeType 下有 Begin End 我想添加一个约束说 Begin 非常
我想声明一个要包含在复杂类型声明中的元素,并且该元素有一个强制属性:“option=MyOption”,但是“选项”属性的值可以是任何值,具体取决于上下文。 也就是说:在使用包含该元素的复杂类型的任何
我需要能够将简单元素类型设置为整数,但也可以将其设置为空。如果此示例为空且空白字段不是整数,则此示例将发送错误。我该如何解决? 最佳答案 您要做的是在同一元素上分配限制,并对其进行合并,例如以下示例
对于这个 xml: 我有这个模式,它似乎可以根据 w3 schema validation service 进行验证,并且该架构可以很好地验证上述 XML。遗憾的是,xsd.exe
我有两个 XSD 文件(源文件和目标文件)...我应该在什么基础上映射这两个文件以获得 XSLT?我知道 MapForce 如何帮助映射,但我使用示例项目..现在我想知道我应该在什么基础上映射我的客户
我有一个 .cs 文件,其中包含 XTypedElement 和 IXMetaData 的子类。微软有一个 tool that generates XSD files automatically来自托
这个问题在这里已经有了答案: XML Schema to validate XML Schemas? (3 个答案) 关闭 9 年前。 是否存在可验证其他 XML 架构的 Xml 架构? 我想做的是
假设我正在处理一个 xsd:simpleType,它是一个字符串,需要具有特定的字符集和特定的最大长度,类似于以下代码: 所以我的 xsd 类型将是一个只
JAXB 同时映射 xsd:base64Binary和 xsd:hexBinary类型为 byte[] . 鉴于我有一个架构/DOM 元素代表这些类型中的每一个,例如: ABCD对于 xsd:hexB
我非常确定我在这里遗漏了一些简单的东西。 我正在使用 netbeans 在两个单独的项目中创建一个 web jax-ws web 服务和一个客户端,并且我有一些自定义绑定(bind)已使用 net b
将字节数组表示为 XSD 架构的最佳方式是什么?我有一个字节输入,我需要解析它并将其提供给 JAXB 从 XSD 模式生成的 Java 对象以供将来验证。我输入中的每条信息都由偏移量和长度定义。我想将
我的架构的这一部分给我带来了麻烦:
我需要定义元素“MyData”的名为“DataValue”的属性。但要求是“DataValue”的类型可以动态更改,即数据值在一个实例中可以是字符串,而在其他实例中它可以是 int 或 bool。它可
我是一名优秀的程序员,十分优秀!