diff --git a/crates/preflight/src/tests.rs b/crates/preflight/src/tests.rs
index d00cc9581c..51b1e3d85b 100644
--- a/crates/preflight/src/tests.rs
+++ b/crates/preflight/src/tests.rs
@@ -576,6 +576,9 @@ fn xmp_arrays_have_their_kind_and_item_types() {
// Only white space around an array's items.
assert_eq!(element("dc:creator", "strayA"), ["dc:creator"]);
assert_eq!(element("dc:creator", "strayA"), ["dc:creator"]);
+ // rdf:parseType or rdf:resource on the property makes its value something other than the array.
+ assert_eq!(mistyped(r#">A"#), ["dc:creator"]);
+ assert_eq!(mistyped(r#">A"#), ["dc:creator"]);
assert!(element("dc:creator", "\n \n A\n \n").is_empty());
// An rdf:resource element is empty.
assert_eq!(mistyped(r#">x"#), ["dc:source"]);
diff --git a/crates/preflight/src/xmp_types.rs b/crates/preflight/src/xmp_types.rs
index 29f1457947..3e77332972 100644
--- a/crates/preflight/src/xmp_types.rs
+++ b/crates/preflight/src/xmp_types.rs
@@ -755,8 +755,9 @@ fn field(fields: &[Field], ns: &str, name: &str) -> Option {
fn array<'a, 'i>(e: &Node<'a, 'i>, children: &[Node<'a, 'i>], kind: &str) -> Option>> {
match children {
// Items are `rdf:li` (ISO 16684-1 7.9.2.4); any other element, or character data around
- // them, breaks the array.
- [a] if is(a, RDF, kind) && field_attributes(e).next().is_none() && blank(e) && blank(a) => {
+ // them, breaks the array, and so does `rdf:parseType` or `rdf:resource` on the property,
+ // which makes its value something else.
+ [a] if is(a, RDF, kind) && field_attributes(e).next().is_none() && blank(e) && blank(a) && !other_value_form(e) => {
let items: Vec> = a.children().filter(Node::is_element).collect();
items.iter().all(|i| is(i, RDF, "li")).then_some(items)
}
@@ -778,6 +779,11 @@ fn structure<'a, 'i>(e: &Node<'a, 'i>, children: &[Node<'a, 'i>], resource: bool
(children.is_empty() && empty && e.attribute((RDF, "resource")).is_none() && field_attributes(e).next().is_some()).then_some(*e)
}
+/// Whether `e` says its value is a resource or a literal of another kind, not the element it holds.
+fn other_value_form(e: &Node<'_, '_>) -> bool {
+ e.attribute((RDF, "parseType")).is_some() || e.attribute((RDF, "resource")).is_some()
+}
+
/// Whether `e` holds no character data but white space.
fn blank(e: &Node<'_, '_>) -> bool {
text(e).trim().is_empty()