| 938 | // It also catches and cleans up qualified properties written with rdf:Description and rdf:value. |
| 939 | |
| 940 | static void |
| 941 | RDF_ResourcePropertyElement ( XMP_Node * xmpParent, const XML_Node & xmlNode, bool isTopLevel ) |
| 942 | { |
| 943 | if ( isTopLevel && (xmlNode.name == "iX:changes") ) return; // Strip old "punchcard" chaff. |
| 944 | |
| 945 | XMP_Node * newCompound = AddChildNode ( xmpParent, xmlNode, "", isTopLevel ); |
| 946 | |
| 947 | XML_cNodePos currAttr = xmlNode.attrs.begin(); |
| 948 | XML_cNodePos endAttr = xmlNode.attrs.end(); |
| 949 | |
| 950 | for ( ; currAttr != endAttr; ++currAttr ) { |
| 951 | XMP_VarString & attrName = (*currAttr)->name; |
| 952 | if ( attrName == "xml:lang" ) { |
| 953 | AddQualifierNode ( newCompound, **currAttr ); |
| 954 | } else if ( attrName == "rdf:ID" ) { |
| 955 | continue; // Ignore all rdf:ID attributes. |
| 956 | } else { |
| 957 | XMP_Throw ( "Invalid attribute for resource property element", kXMPErr_BadRDF ); |
| 958 | } |
| 959 | } |
| 960 | |
| 961 | XML_cNodePos currChild = xmlNode.content.begin(); |
| 962 | XML_cNodePos endChild = xmlNode.content.end(); |
| 963 | |
| 964 | for ( ; currChild != endChild; ++currChild ) { |
| 965 | if ( ! (*currChild)->IsWhitespaceNode() ) break; |
| 966 | } |
| 967 | if ( currChild == endChild ) XMP_Throw ( "Missing child of resource property element", kXMPErr_BadRDF ); |
| 968 | if ( (*currChild)->kind != kElemNode ) XMP_Throw ( "Children of resource property element must be XML elements", kXMPErr_BadRDF ); |
| 969 | |
| 970 | if ( (*currChild)->name == "rdf:Bag" ) { |
| 971 | newCompound->options |= kXMP_PropValueIsArray; |
| 972 | } else if ( (*currChild)->name == "rdf:Seq" ) { |
| 973 | newCompound->options |= kXMP_PropValueIsArray | kXMP_PropArrayIsOrdered; |
| 974 | } else if ( (*currChild)->name == "rdf:Alt" ) { |
| 975 | newCompound->options |= kXMP_PropValueIsArray | kXMP_PropArrayIsOrdered | kXMP_PropArrayIsAlternate; |
| 976 | } else { |
| 977 | newCompound->options |= kXMP_PropValueIsStruct; |
| 978 | if ( (*currChild)->name != "rdf:Description" ) { |
| 979 | XMP_VarString typeName ( (*currChild)->ns ); |
| 980 | size_t colonPos = (*currChild)->name.find_first_of(':'); |
| 981 | if ( colonPos == XMP_VarString::npos ) XMP_Throw ( "All XML elements must be in a namespace", kXMPErr_BadXMP ); |
| 982 | typeName.append ( (*currChild)->name, colonPos, XMP_VarString::npos ); |
| 983 | AddQualifierNode ( newCompound, XMP_VarString("rdf:type"), typeName ); |
| 984 | } |
| 985 | } |
| 986 | |
| 987 | RDF_NodeElement ( newCompound, **currChild, kNotTopLevel ); |
| 988 | if ( newCompound->options & kRDF_HasValueElem ) { |
| 989 | FixupQualifiedNode ( newCompound ); |
| 990 | } else if ( newCompound->options & kXMP_PropArrayIsAlternate ) { |
| 991 | DetectAltText ( newCompound ); |
| 992 | } |
| 993 | |
| 994 | for ( ++currChild; currChild != endChild; ++currChild ) { |
| 995 | if ( ! (*currChild)->IsWhitespaceNode() ) XMP_Throw ( "Invalid child of resource property element", kXMPErr_BadRDF ); |
| 996 | } |
| 997 |
no test coverage detected