問(wèn)題描述
我正在編寫(xiě) xsd 和要驗(yàn)證的代碼,所以我在這里可以很好地控制.
I'm writing the xsd and the code to validate, so I have great control here.
我想要一個(gè)上傳工具,可以根據(jù) xml 文件向我的應(yīng)用程序添加內(nèi)容.xml 文件的一部分應(yīng)根據(jù)另一部分中的值之一針對(duì)不同的模式進(jìn)行驗(yàn)證.下面舉個(gè)例子來(lái)說(shuō)明:
I would like to have an upload facility that adds stuff to my application based on an xml file. One part of the xml file should be validated against different schemas based on one of the values in the other part of it. Here's an example to illustrate:
<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>
的內(nèi)容有一些受控詞匯,我可以很好地處理這部分.然后,根據(jù) bar 值,應(yīng)使用適當(dāng)?shù)?xml 模式來(lái)驗(yàn)證 bar-config 的內(nèi)容.對(duì)于 baz 和 baz-config 也是如此.
In this case, there is some controlled vocabulary for the content of <bar>
, and I can handle that part just fine. Then, based on the bar value, the appropriate xml schema should be used to validate the content of bar-config. Similarly for baz and baz-config.
進(jìn)行解析/驗(yàn)證的代碼是用 Java 編寫(xiě)的.不確定解決方案對(duì)語(yǔ)言的依賴性.
The code doing the parsing/validation is written in Java. Not sure how language-dependent the solution will be.
理想情況下,該解決方案將允許 xml 作者聲明適當(dāng)?shù)募軜?gòu)位置和其他內(nèi)容,以便他/她可以在足夠智能的編輯器中即時(shí)驗(yàn)證 xml.
Ideally, the solution would permit the xml author to declare the appropriate schema locations and what-not so that s/he could get the xml validated on the fly in a sufficiently smart editor.
另外,<bar>
和 <baz>
的可能值是正交的,所以我不想通過(guò)擴(kuò)展來(lái)對(duì)每個(gè)可能的條進(jìn)行此操作/baz 組合.我的意思是,如果有 24 個(gè)可能的 bar 值/模式和 8 個(gè)可能的 baz 值/模式,我希望能夠編寫(xiě) 1 + 24 + 8 = 33 個(gè)總模式,而不是 1 * 24 * 8 = 192 個(gè)總模式.
Also, the possible values for <bar>
and <baz>
are orthogonal, so I don't want to do this by extension for every possible bar/baz combo. What I mean is, if there are 24 possible bar values/schemas and 8 possible baz values/schemas, I want to be able to write 1 + 24 + 8 = 33 total schemas, instead of 1 * 24 * 8 = 192 total schemas.
另外,如果可能的話,我不希望將 bar-config 和 baz-config 拆分為單獨(dú)的 xml 文件.我意識(shí)到這可能會(huì)使所有問(wèn)題變得更容易,因?yàn)槊總€(gè) xml 文件都有一個(gè)單一的架構(gòu),但我正在嘗試看看是否有一個(gè)好的單 xml 文件解決方案.
Also, I'd prefer to NOT break out the bar-config and baz-config into separate xml files if possible. I realize that might make all the problems much easier, as each xml file would have a single schema, but I'm trying to see if there is a good single-xml-file solution.
推薦答案
我終于想通了.
首先,在 foo 模式中,bar-config 和 baz-config 元素的類型包含 any
元素,如下所示:
First of all, in the foo schema, the bar-config and baz-config elements have a type which includes an any
element, like this:
<sequence>
<any minOccurs="0" maxOccurs="1"
processContents="lax" namespace="##any" />
</sequence>
那么,在 xml 中,您必須使用 bar-config 或 baz-config 的子元素上的 xmlns
屬性指定正確的命名空間,如下所示:
In the xml, then, you must specify the proper namespace using the xmlns
attribute on the child element of bar-config or baz-config, like this:
<bar-config>
<config xmlns="http://www.example.org/bar/Alpha">
... config xml here ...
</config>
</bar-config>
然后,bar Alpha 的 XML 模式文件將具有 http://www.example 的目標(biāo)命名空間.org/bar/Alpha 并將定義根元素 config
.
Then, your XML schema file for bar Alpha will have a target namespace of http://www.example.org/bar/Alpha and will define the root element config
.
如果您的 XML 文件具有兩個(gè)模式文件的名稱空間聲明和模式位置,這足以讓編輯器完成所有驗(yàn)證(至少對(duì) Eclipse 來(lái)說(shuō)足夠好).
If your XML file has namespace declarations and schema locations for both of the schema files, this is sufficient for the editor to do all of the validating (at least good enough for Eclipse).
到目前為止,我們已經(jīng)滿足了xml作者可以以在編輯器中驗(yàn)證的方式編寫(xiě)xml的要求.
So far, we have satisfied the requirement that the xml author may write the xml in such a way that it is validated in the editor.
現(xiàn)在,我們需要消費(fèi)者能夠進(jìn)行驗(yàn)證.就我而言,我使用的是 Java.
Now, we need the consumer to be able to validate. In my case, I'm using Java.
如果您有機(jī)會(huì)提前知道需要用于驗(yàn)證的架構(gòu)文件,那么您只需創(chuàng)建一個(gè) Schema 對(duì)象并照常進(jìn)行驗(yàn)證,如下所示:
If by some chance, you know the schema files that you will need to use to validate ahead of time, then you simply create a single Schema object and validate as usual, like this:
Schema schema = factory().newSchema(new Source[] {
new StreamSource(stream("foo.xsd")),
new StreamSource(stream("Alpha.xsd")),
new StreamSource(stream("Mercury.xsd")),
});
然而,在這種情況下,在我們解析主文檔之前,我們不知道要使用哪些 xsd 文件.所以,一般的程序是:
In this case, however, we don't know which xsd files to use until we have parsed the main document. So, the general procedure is to:
- 僅使用主 (foo) 架構(gòu)驗(yàn)證 xml
- 確定用于驗(yàn)證文檔部分的架構(gòu)
- 使用單獨(dú)的架構(gòu)查找作為要驗(yàn)證的部分的根節(jié)點(diǎn)
- 將該節(jié)點(diǎn)導(dǎo)入到一個(gè)全新的文檔中
- 使用其他架構(gòu)文件驗(yàn)證全新的文檔
注意事項(xiàng):似乎必須構(gòu)建可識(shí)別命名空間的文檔才能使其正常工作.
這是一些代碼(這是從我的代碼的各個(gè)地方撕下來(lái)的,所以復(fù)制和粘貼可能會(huì)引入一些錯(cuò)誤):
Here's some code (this was ripped from various places of my code, so there might be some errors introduced by the copy-and-paste):
// 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));
這篇關(guān)于要針對(duì)多個(gè) xsd 模式驗(yàn)證 XML的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!