Merge epic/79-rnc-nameclass-subtraction: name-class subtraction

Part of #79
This commit is contained in:
Mihaela Mihaljevic 2026-06-08 16:58:24 +02:00
commit 2dfa647111
2 changed files with 27 additions and 0 deletions

View File

@ -308,6 +308,11 @@ private extension RNCParser {
switch peek() {
case .symbol("*"):
advance()
// `* - nameClass` is any name except the subtracted class.
if peek() == .symbol("-") {
advance()
return .anyNameExcept(parseSimpleNameClass(attribute: attribute))
}
return .anyName
case .symbol("("):
advance()

View File

@ -0,0 +1,22 @@
@testable import PureXML
import Testing
@Suite("RELAX NG compact name-class subtraction")
struct RelaxNGNameClassTests {
private func valid(_ rnc: String, _ xml: String) throws -> Bool {
try PureXML.Schema.RelaxNG(compact: rnc).validate(xml)
}
@Test("* - name admits any element except the subtracted one")
func test_subtraction() throws {
let rnc = "element root { element * - skip { empty }* }"
#expect(try valid(rnc, "<root><a/><b/></root>"))
#expect(try !valid(rnc, "<root><skip/></root>"))
}
@Test("A plain wildcard still admits everything")
func test_plainWildcard() throws {
let rnc = "element root { element * { empty }* }"
#expect(try valid(rnc, "<root><skip/><a/></root>"))
}
}