我编写了以下(简化)架构来验证我收到的一些XML文件:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Param">
<xs:complexType>
<xs:sequence>
<xs:element name="RadioAddr" type="xs:string" />
<xs:element name="DataToRead" type="xs:integer" minOccurs="0" maxOccurs="1" />
<xs:choice minOccurs="0" maxOccurs="1">
<xs:group ref="Group1" />
<xs:group ref="Group2" />
<xs:group ref="Group3" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="Group1">
<xs:sequence>
<xs:element ref="Password" />
<xs:element name="RadioActivated" type="xs:integer" minOccurs="0" maxOccurs="1" />
<xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
<xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:group>
<xs:group name="Group2">
<xs:sequence>
<xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
<xs:element ref="Password" />
<xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:group>
<xs:group name="Group3">
<xs:sequence>
<xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
<!-- No password here -->
<xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:group>
<xs:element name="Password" type="xs:string" />
<xs:element name="IdNumber" type="xs:integer" />
<xs:element name="AdjustClock" type="xs:integer" />
</xs:schema>
验证此架构时,我收到以下错误消息:
无效。错误 - 第5行,第25行:org.xml.sax.SAXParseException; lineNumber:5; columnNumber:25; cos-nonambig:密码和密码 (或来自其替代组的元素)违反“独特粒子” 归因“。在对此模式进行验证期间,歧义会出现歧义 为这两个粒子创建。
我完全理解这种模糊性,但我找不到使我的模式有效的解决方案。
可能的解决方案是做类似
的事情<xs:element name="Param>
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<!-- put all the possible elements here -->
</xs:choice>
</xs:complexType>
</xs:element>
但是我对这个解决方案的问题是我失去了一个对我有用的抽象级别(组)(我使用这个模式用JAXB生成Java类)。
那么,有没有办法使用<xs:group>
使我的架构有效,或者我必须展平我的架构(就像我上面提到的解决方案一样)?
以下是XSD应该允许的示例:
允许的最小值:
<Param>
<RadioAddr>1</RadioAddr>
</Param>
也是合法的:
<Param>
<RadioAddr>1</RadioAddr>
<Password>1234</Password>
</Param>
<Param>
<RadioAddr>1</RadioAddr>
<Password>1234</Password>
<RadioActivated>1</RadioActivated>
<IdNumber>12345678</IdNumber>
</Param>
<Param>
<RadioAddr>1</RadioAddr>
<IdNumber>12345678</IdNumber>
<Password>1234</Password>
</Param>
答案 0 :(得分:4)
要击败Unique Particle Attribution违规,您必须允许解析器明确地知道它在语法中的位置,而不必向前看多个元素。
出现当前错误是因为无法知道何时遇到Password
元素,解析器是Group1
还是Group2
,因为IdNumber
是可选的。您可以强制使用IdNumber
,但这会在Group2
和Group3
之间IdNumber
之间产生歧义。然后,您可以尝试使用排序来区分xs:choice
组,但之后您会发现元素的可选性会破坏您的努力。您可以删除选项,如果组之间的顺序不同,那么您可以得到答案。
然而,这将是一个相当奇怪的语法。在那一点上,你可能会更好地扁平化,但是你可以通过一个无限制的xs:choice
,它可以允许任意和无界的元素重复,而不是使用无界xs:sequence
。简单的<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Param">
<xs:complexType>
<xs:sequence>
<xs:element name="RadioAddr" type="xs:string" />
<xs:element name="DataToRead" type="xs:integer" minOccurs="0" maxOccurs="1" />
<xs:element name="RadioActivated" type="xs:integer" minOccurs="0" maxOccurs="1" />
<xs:element ref="IdNumber" minOccurs="0" maxOccurs="1" />
<xs:element ref="Password" minOccurs="0"/>
<xs:element ref="AdjustClock" minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Password" type="xs:string" />
<xs:element name="IdNumber" type="xs:integer" />
<xs:element name="AdjustClock" type="xs:integer" />
</xs:schema>
元素代替:
$('tr.invoicerow').each(function () {
var RowProductNames = $(this).find("input.invoiceproduct").val();
if (RowProductNames == InvoiceProductName) {
var c=parseInt($(this).find("td input.invoicerate").val())+parseInt(USER_INPUTTED_VALUE);
$(this).find("td input.invoicerate").val(c);
} else {
row = "<tr class='invoicerow'><td hidden><input class='dcid' value=" + deliverychallanid + "></td><td><input class='case invoicechkbox' type='checkbox'></td><td><input class='form-control invoiceproduct' id='invoiceproduct_" + rowno + "' value=" + InvoiceProductName + "></td><td><input class='form-control invoiceunit' id='invoiceunit_" + rowno + "' value=" + InvoiceUnit + "></td><td><input class='form-control invoicerate' id='invoicerate_" + rowno + "' value=" + InvoiceRatePerUnit + "></td><td><input class='form-control invoicenos' id='invoicenos_" + rowno + "'value=" + 0 + "></td><td><input class='form-control invoicequantity' id='invoicequantity_" + rowno + "' value=" + 0 + "></td><td><input class='form-control invoicecapacity' id='invoicecapacity_" + rowno + "'value=" + value.Capacity + "></td><td><input class='form-control invoiceamount' id='invoiceamount_" + rowno + "' value=" + Totalamount + "></td></tr>"
$('#invoicebody').append(row);
}
});
}