[英]XML to be validated against multiple xsd schemas
我正在寫xsd和代碼來驗證,所以我在這里有很好的控制權。
我想有一個上傳工具,可以根據xml文件向我的應用程序添加內容。 應根據其他部分中的某個值,針對不同的模式驗證xml文件的一部分。 這是一個例子來說明:
<foo>
<name>Harold</name>
<bar>Alpha</bar>
<baz>Mercury</baz>
<!-- ... more general info that applies to all foos ... -->
<bar-config>
<!-- the content here is specific to the bar named "Alpha" -->
</bar-config>
<baz-config>
<!-- the content here is specific to the baz named "Mercury" -->
</baz>
</foo>
在這種情況下, <bar>
的內容有一些受控的詞匯表,我可以很好地處理那部分。 然后,根據條形值,應使用適當的xml架構來驗證bar-config的內容。 同樣適用於baz和baz-config。
執行解析/驗證的代碼是用Java編寫的。 不確定解決方案的語言依賴性。
理想情況下,該解決方案將允許xml作者聲明適當的模式位置以及什么不是,以便他/她可以在足夠智能的編輯器中動態驗證xml。
此外, <bar>
和<baz>
的可能值是正交的,因此我不希望通過擴展為每個可能的bar / baz組合執行此操作。 我的意思是,如果有24個可能的條形值/模式和8個可能的baz值/模式,我希望能夠寫出1 + 24 + 8 = 33個總模式,而不是1 * 24 * 8 = 192個模式。
另外,如果可能的話,我寧願不將bar-config和baz-config分解成單獨的xml文件。 我意識到可能會使所有問題變得更容易,因為每個xml文件都有一個模式,但我正在嘗試查看是否有一個好的單xml文件解決方案。
我終於想通了。
首先,在foo架構中,bar-config和baz-config元素的類型包含any
元素,如下所示:
<sequence>
<any minOccurs="0" maxOccurs="1"
processContents="lax" namespace="##any" />
</sequence>
在xml中,您必須使用bar-config或baz-config的子元素上的xmlns
屬性指定正確的命名空間,如下所示:
<bar-config>
<config xmlns="http://www.example.org/bar/Alpha">
... config xml here ...
</config>
</bar-config>
然后,條形Alpha的XML模式文件將具有http://www.example.org/bar/Alpha的目標名稱空間,並將定義根元素config
。
如果您的XML文件具有兩個模式文件的名稱空間聲明和模式位置,那么編輯器就可以完成所有驗證(至少對Eclipse來說足夠好)。
到目前為止,我們已經滿足了xml作者可能以在編輯器中驗證它的方式編寫xml的要求。
現在,我們需要消費者能夠驗證。 就我而言,我正在使用Java。
如果有可能,您知道需要用於提前驗證的模式文件,那么您只需創建一個Schema對象並像往常一樣進行驗證,如下所示:
Schema schema = factory().newSchema(new Source[] {
new StreamSource(stream("foo.xsd")),
new StreamSource(stream("Alpha.xsd")),
new StreamSource(stream("Mercury.xsd")),
});
但是,在這種情況下,在解析主文檔之前,我們不知道要使用哪些xsd文件。 因此,一般程序是:
警告:似乎必須構建文檔名稱空間才能使其正常工作。
這是一些代碼(這是從我的代碼的各個地方撕掉的,因此復制和粘貼可能會引入一些錯誤):
// Contains the filename of the xml file
String filename;
// Load the xml data using a namespace-aware builder (the method
// 'stream' simply opens an input stream on a file)
Document document;
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
document = docBuilderFactory.newDocumentBuilder().parse(stream(filename));
// Create the schema factory
SchemaFactory sFactory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
// Load the main schema
Schema schema = sFactory.newSchema(
new StreamSource(stream("foo.xsd")));
// Validate using main schema
schema.newValidator().validate(new DOMSource(document));
// Get the node that is the root for the portion you want to validate
// using another schema
Node node= getSpecialNode(document);
// Build a Document from that node
Document subDocument = docBuilderFactory.newDocumentBuilder().newDocument();
subDocument.appendChild(subDocument.importNode(node, true));
// Determine the schema to use using your own logic
Schema subSchema = parseAndDetermineSchema(document);
// Validate using other schema
subSchema.newValidator().validate(new DOMSource(subDocument));
看看NVDL(基於命名空間的驗證調度語言) - http://www.nvdl.org/
它旨在執行您想要執行的操作(驗證具有自己的命名空間和模式的XML文檔的部分)。
這里有一個教程 - http://www.dpawson.co.uk/nvdl/ - 這里有一個Java實現 - http://jnvdl.sourceforge.net/
希望有所幫助! 凱文
你也可以使用“資源解析器”來允許“xml authors”指定自己的模式文件,至少在某種程度上,例如: https : //stackoverflow.com/a/41225329/32453 ,在一天結束時,你想要一個完全兼容的xml文件,無論如何都可以用普通工具驗證:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.