XML Schema如何禁止未定义元素?为何XMLSpy仅报def错而非abc?
def Throws an Error But abc Doesn’t (And How to Block All Undefined Elements) Alright, let’s unpack your problem first. The fact that one undefined element (def) errors out while another (abc) doesn’t almost always boils down to namespace configuration and how your XML Schema (XSD) handles element validation rules. Here’s the breakdown:
Common Causes of the Mismatched Behavior
1. Namespace Differences
XML Schema only enforces rules for elements in its declared targetNamespace by default. If:
defbelongs to your schema’s target namespace (e.g., it uses the same prefix as your defined elements, or your instance uses that namespace as the default), the validator will flag it as undefined.abcis in no namespace (or a different namespace your schema doesn’t restrict), the validator will ignore it unless you explicitly tell it to check those namespaces.
2. Accidental Wildcard Allowances
If your schema includes an <xs:any> wildcard (a common way to allow extensibility), its processContents attribute determines how undefined elements are handled:
processContents="skip": The validator ignores elements matching the wildcard (this would letabcslip through if it falls under the wildcard’s namespace rules).processContents="strict": It validates those elements against the schema (sodefwould error if it’s in the target namespace but undefined).
3. elementFormDefault Misconfiguration
If your schema uses elementFormDefault="unqualified", local elements don’t need a namespace prefix. This can create confusion: elements without a prefix might be treated as "unqualified" (no namespace) and not validated against your target namespace’s rules, while prefixed elements (like def) are checked strictly.
How to Block All Undefined Elements
To lock down your schema so no undefined elements (regardless of namespace) are allowed, follow these steps:
1. Enforce a Target Namespace with Qualified Elements
First, define a clear target namespace and require all instance elements to use it:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://your-feedback-schema.com" xmlns:fb="http://your-feedback-schema.com" elementFormDefault="qualified"> <!-- Your schema definitions go here --> </xs:schema>
targetNamespace: Assigns all your defined elements to this namespace.elementFormDefault="qualified": Ensures every element in the instance must belong to this namespace (via prefix or default namespace declaration).
2. Use a Closed Content Model for the Root Element
Make sure your root element’s content model only includes explicitly defined elements—no wildcards that allow arbitrary additions:
<xs:element name="FeedbackReport"> <xs:complexType> <xs:sequence> <xs:element name="ReporterInfo" type="fb:ReporterType"/> <xs:element name="DataFeedback" type="fb:FeedbackType"/> <!-- No <xs:any> here—only the elements you define are allowed --> </xs:sequence> </xs:complexType> </xs:element>
3. Explicitly Block Non-Target Namespace Elements
If you want to block elements from other namespaces (including no namespace), add a wildcard that forbids them:
<xs:element name="FeedbackReport"> <xs:complexType> <xs:sequence> <xs:element name="ReporterInfo" type="fb:ReporterType"/> <xs:element name="DataFeedback" type="fb:FeedbackType"/> <!-- Block all elements not in your target namespace --> <xs:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element>
namespace="##other": Targets all elements not in your schema’s target namespace.maxOccurs="0": Prohibits any such elements entirely.processContents="strict": Ensures even if someone tries to add them, they’ll throw an error (instead of being ignored).
4. Verify XMLSpy’s Validation Settings
In XMLSpy, double-check that you’re using strict validation mode:
- Go to
Validation > Validation Scenarioand confirm the scenario uses your schema withProcess Contentsset toStrict. - Avoid
LaxorSkipmodes, which can let undefined elements pass.
Example: Locked-Down Schema + Invalid Instance
Schema (feedback-schema.xsd)
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://your-feedback-schema.com" xmlns:fb="http://your-feedback-schema.com" elementFormDefault="qualified"> <xs:element name="FeedbackReport"> <xs:complexType> <xs:sequence> <xs:element name="ReporterInfo" type="fb:ReporterType"/> <xs:element name="DataFeedback" type="fb:FeedbackType"/> <xs:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="ReporterType"> <xs:sequence> <xs:element name="Name" type="xs:string"/> <xs:element name="ID" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="FeedbackType"> <xs:sequence> <xs:element name="DataPoint" type="fb:DataPointType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="DataPointType"> <xs:sequence> <xs:element name="FieldName" type="xs:string"/> <xs:element name="Comment" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
Invalid Instance (feedback.xml)
<?xml version="1.0" encoding="UTF-8"?> <fb:FeedbackReport xmlns:fb="http://your-feedback-schema.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://your-feedback-schema.com feedback-schema.xsd"> <fb:ReporterInfo> <fb:Name>John Doe</fb:Name> <fb:ID>REP-123</fb:ID> </fb:ReporterInfo> <fb:DataFeedback> <fb:DataPoint> <fb:FieldName>UserAge</fb:FieldName> <fb:Comment>Invalid format</fb:Comment> </fb:DataPoint> </fb:DataFeedback> <fb:abc/> <!-- Errors: Undefined element in target namespace --> <def/> <!-- Errors: Element in no namespace (blocked by wildcard) --> </fb:FeedbackReport>
Now both abc and def will throw validation errors in XMLSpy, exactly what you want.
内容的提问来源于stack exchange,提问作者Paul

