假设我有一个XML文档(表示为文本,W3C DOM,无论如何),还有一个XML Schema.XML文档具有模式定义的所有正确元素,但顺序错误.
如何使用模式"重新排序"文档中的元素以符合模式定义的顺序?
我知道这应该是可能的,可能使用XSOM,因为JAXB XJC代码生成器使用元素的正确序列化顺序来注释其生成的类.
但是,我不熟悉XSOM API,它非常密集,所以我希望你们中的一个人有一些经验,可以指出我正确的方向.像"在这个父元素中允许哪些子元素,以什么顺序?"之类的东西.
让我举个例子.
我有一个像这样的XML文档:
<A>
<Y/>
<X/>
</A>
Run Code Online (Sandbox Code Playgroud)
我有一个XML Schema,它说<A>必须是一个<X>后跟a的内容<Y>.现在显然,如果我尝试根据模式验证文档,它会失败,因为<X>并且<Y>顺序错误.但我知道我的文档提前是"错误的",所以我还没有使用模式进行验证.不过,我不知道,我的文档具有所有正确的元素由模式只是在错误的顺序定义.
我想要做的是以编程方式检查Schema(可能使用XSOM - 这是XML Schema的对象模型),并询问它<A>应该是什么内容.API将公开"您需要<X>后跟a <Y>"的信息.
所以我使用我的XML文档(使用DOM API)并相应地重新安排,以便现在文档将根据模式进行验证.
了解XSOM在这里是什么很重要 - 它是一个java API,它表示XML Schema中包含的信息,而不是我的实例文档中包含的信息.
我不想做的是从架构生成代码,因为架构在构建时是未知的.此外,XSLT没有用,因为元素的正确排序仅由模式中包含的数据字典决定.
希望现在已经足够明确了.
小智 5
我被同样的问题困扰了大约两周。终于我得到了突破。这可以使用 JAXB 编组/解组功能来实现。
在 JAXB marshal/unmarshal 中,XML 验证是一个可选功能。因此,在创建 Marshaller 和 UnMarshaller 对象时,我们不调用 setSchema(schema) 方法。省略此步骤可以避免 marshal/unmarshal 的 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();
}
}
Run Code Online (Sandbox Code Playgroud)
您的问题转化为:您有一个与架构不匹配的 XSM 文件,并且您希望将其转换为有效的文件。
使用 XSOM,您可以读取 XSD 中的结构,或许还可以分析 XML,但它仍然需要从无效表单到有效表单的额外映射。使用样式表会容易得多,因为您将遍历 XML,使用 XPath 节点以正确的顺序处理元素。对于 XML,如果您希望先有苹果,后有梨,则样式表将首先复制苹果节点 (/Fruit/Apple),然后再复制梨节点。这样,无论旧文件中的顺序如何,它们在新文件中的顺序都是正确的。
您可以使用 XSOM 读取 XSD 并生成对数据重新排序的样式表。然后使用该样式表转换 XML。一旦 XSOM 为 XSD 生成了样式表,您就可以重复使用该样式表,直到 XSD 被修改或需要另一个 XSD。
当然,您可以使用 XSOM 以正确的顺序立即复制节点。但是,由于这意味着您的代码必须自行遍历所有节点和子节点,因此可能需要一些时间才能完成处理。样式表可以做同样的事情,但是转换器将能够更快地处理它。它可以直接处理数据,而 Java 代码必须通过 XMLDocument 属性获取/设置每个节点。
当我想到这一点时,我想知道以前是否已经这样做过。它将非常通用并且能够处理几乎所有 XSD/XML。
让我们看看...使用“//xsd:element/@name”您将获得架构中的所有元素名称。每个唯一的名称都需要翻译成模板。在这些模板中,您需要处理特定元素的子节点,这稍微复杂一些。元素可以有一个参考,您需要遵循该参考。否则,获取它的所有子 xsd:element 节点。
| 归档时间: |
|
| 查看次数: |
5377 次 |
| 最近记录: |