gpt4 book ai didi

java - 使用模式根据模式重新排序 XML 文档的元素

转载 作者:数据小太阳 更新时间:2023-10-29 01:54:45 25 4
gpt4 key购买 nike

假设我有一个 XML 文档(表示为文本、W3C DOM 等),还有一个 XML 模式。 XML 文档具有架构定义的所有正确元素,但顺序错误。

如何使用模式对文档中的元素进行“重新排序”以符合模式定义的顺序?

我知道这应该是可能的,可能使用 XSOM ,因为 JAXB XJC 代码生成器使用元素的正确序列化顺序注释其生成的类。

但是,我对 XSOM API 并不熟悉,而且它非常密集,所以我希望你们中的一些人对此有一些经验,并能为我指明正确的方向。类似于“此父元素内允许使用哪些子元素,以什么顺序排列?”


我举个例子。

我有一个这样的 XML 文档:

<A>
<Y/>
<X/>
</A>

我有一个 XML 模式,它表示 <A> 的内容必须是 <X>其次是 <Y> .现在很明显,如果我尝试根据模式验证文档,它会失败,因为 <X><Y>顺序错误。但是我事先知道我的文档是“错误的”,所以我还没有使用模式来验证。但是,我确实知道我的文档包含架构定义的所有正确元素,只是顺序错误。

我想做的是以编程方式检查架构(可能使用 XSOM - 它是 XML 架构的对象模型),并询问 <A> 的内容是什么应该。 API 将公开“您需要一个 <X> 后跟一个 <Y>”的信息。

所以我使用我的 XML 文档(使用 DOM API)并相应地重新安排,这样现在文档将根据模式进行验证。

了解此处的 XSOM 是什么很重要 - 它是一个 java API,表示 XML 模式中包含的信息,不是我的实例文档中包含的信息。

我不想做的是从模式生成代码,因为模式在构建时是未知的。此外,XSLT 没有用,因为元素的正确排序仅由模式中包含的数据字典决定。

希望现在已经足够明确了。

最佳答案

我被同样的问题困扰了大约两周。最后我得到了突破。这可以使用 JAXB 编码/解码功能来实现。

在 JAXB 编码/解码中,XML 验证是一项可选功能。因此,在创建 Marshaller 和 UnMarshaller 对象时,我们不调用 setSchema(schema) 方法。省略此步骤可避免 marshal/unmarshal 的 XML 验证功能。

现在,

  1. 如果 XML 中没有任何 XSD 规定的强制元素,则忽略它。
  2. 如果 XSD 中不存在的任何标记在 XML 中存在,则不会抛出错误,并且在编码/解码后获得的新 XML 中也不存在。
  3. 如果元素不按顺序,它们将重新排序。这是由我们在创建 JAXBContext 时传递的 JAXB 生成的 POJO 完成的。
  4. 如果某个元素错位在其他标记内,则在新 XML 中将忽略该元素。编码/解码时不会抛出任何错误。

public class JAXBSequenceUtil {
public static void main(String[] args) throws JAXBException, IOException {

String xml = FileUtils.readFileToString(new File(
"./conf/out/Response_103_1015700001&^&IOF.xml"));

System.out.println("Before marshalling : \n" + xml);
String sequencedXml = correctSequence(xml,
"org.acord.standards.life._2");
System.out.println("After marshalling : \n" + sequencedXml);
}

/**
* @param xml
* - XML string to be corrected for sequence.
* @param jaxbPackage
* - package containing JAXB generated classes using XSD.
* @return String - xml with corrected sequence
* @throws JAXBException
*/
public static String correctSequence(String xml, String jaxbPackage)
throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(jaxbPackage);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object txLifeType = unmarshaller.unmarshal(new InputSource(
new StringReader(xml)));
System.out.println(txLifeType);

StringWriter stringWriter = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.marshal(txLifeType, stringWriter);

return stringWriter.toString();
}
}

关于java - 使用模式根据模式重新排序 XML 文档的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1435452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com