免责声明:我是Jsonix 的作者,这是一个模式驱动用于 XMLJS 转换的 JavaScript 库。
Jsonix 似乎完全符合您的要求:
- 您可以从您的架构生成 (JS) 映射
- 使用此映射将您的 XML 解组为 JSON
- 将您的 JSON 编组为 XML
正如您所愿,Jsonix 是 type-aware 和 schema-aware。
类型感知意味着您将在 JSON 中获得一个包含 xs:string 的字符串和一个包含 xs:decimal 等的数字。Jsonix 支持几乎所有内置的 XML Schema 类型(以及您自己的简单类型)派生自内置类型)。
Schema-aware 意味着您的 JSON 结构将严格基于 XML Schema 的结构。您将获得具有可重复元素的数组,依此类推。
在浏览器和 Node.js 中工作,与 AMD 和 CJS 环境兼容。
好了,话不多说,让代码说话吧。
我们采用以下架构(我已将文件命名为 ar.xsd):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="urn:test"
targetNamespace="urn:test"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="AccumulateResponse" type="AccumulateResponse"/>
<xs:complexType name="AccumulateResponse">
<xs:sequence>
<xs:element name="TestCase" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="TransactionId" type="xs:string"/>
<xs:element name="TransactionType" type="xs:string"/>
<xs:element name="Status" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
(我刚刚修改了一个元素名称和命名空间。)
我们首先使用 Jsonix 模式编译器生成映射文件:
java -jar jsonix-schema-compiler-full.jar ar.xsd -p AR
我们从中得到一个名为AR.js 的映射文件,它定义了XML-JSON 映射。这是映射定义的样子:
{
name: 'AR',
defaultElementNamespaceURI: 'urn:test',
typeInfos: [{
localName: 'AccumulateResponse',
propertyInfos: [{
name: 'testCase',
collection: true,
elementName: 'TestCase',
typeInfo: '.AccumulateResponse.TestCase'
}]
}, {
localName: 'AccumulateResponse.TestCase',
propertyInfos: [{
name: 'transactionId',
elementName: 'TransactionId'
}, {
name: 'transactionType',
elementName: 'TransactionType'
}, {
name: 'status',
elementName: 'Status'
}]
}],
elementInfos: [{
elementName: 'AccumulateResponse',
typeInfo: '.AccumulateResponse'
}]
}
(还有一种紧凑模式,您可以在其中获得非常短的名称,例如 en 而不是 elementName。)
接下来是要测试的 XML 示例 (sample01.xml):
<?xml version="1.0" encoding="utf-8"?>
<AccumulateResponse xmlns="urn:test">
<TestCase>
<Transactionid>1234</Transactionid>
<TransactionType>5678</TransactionType>
<Status>Status01</Status>
</TestCase>
<TestCase>
<Transactionid>true</Transactionid>
<TransactionType>false</TransactionType>
<Status>Status02</Status>
</TestCase>
</AccumulateResponse>
这是一个解组测试用例 (ar-tests.js):
var Jsonix = require('jsonix').Jsonix;
var AR = require('../AR').AR;
// Create Jsonix context
var context = new Jsonix.Context([ AR ]);
// Create unmarshaller
var unmarshaller = context.createUnmarshaller();
// Unmarshal the XML file
unmarshaller.unmarshalFile( 'tests/sample01.xml',
function(element) {
console.log(element.value);
test.equal('Status01', element.value.testCase[0].status);
test.done();
});
这就是你在控制台中得到的:
{ TYPE_NAME: 'AR.AccumulateResponse',
testCase:
[ { TYPE_NAME: 'AR.AccumulateResponse.TestCase',
transactionType: '5678',
status: 'Status01' },
{ TYPE_NAME: 'AR.AccumulateResponse.TestCase',
transactionType: 'false',
status: 'Status02' } ] }
编组的工作方式相同。
此示例的完整代码可在here 获得。它是用 Node.js/nodeunit 实现的,但 Jsonix 也可以在浏览器中运行。 (您没有unarshalFile 功能,但您可以使用unmarshalString 或unmarshalDocument 等)
稍后我将发布 JSFiddle 的示例。
几个链接: