private IRdfXmlEvent GetElement() { // Generate Element Event ElementEvent el = new ElementEvent(_reader.Name, GetBaseUri(), _reader.Value, GetPosition()); _requireEndElement = _reader.IsEmptyElement; // Read Attribute Events if (_reader.HasAttributes) { for (int i = 0; i < _reader.AttributeCount; i++) { IRdfXmlEvent attr = GetNextAttribute(); if (attr is AttributeEvent) { el.Attributes.Add((AttributeEvent)attr); } else if (attr is NamespaceAttributeEvent) { el.NamespaceAttributes.Add((NamespaceAttributeEvent)attr); } else if (attr is LanguageAttributeEvent) { el.Language = ((LanguageAttributeEvent)attr).Language; } else if (attr is ParseTypeAttributeEvent) { el.ParseType = ((ParseTypeAttributeEvent)attr).ParseType; el.Attributes.Add(new AttributeEvent(_reader.Name, _reader.Value, _reader.Value, GetPosition())); } else if (attr is XmlBaseAttributeEvent) { el.BaseUri = ((XmlBaseAttributeEvent)attr).BaseUri; _currentBaseUri = el.BaseUri; } } } // Validate generated Attributes for Namespace Confusion and URIRef encoding foreach (AttributeEvent a in el.Attributes) { // Namespace Confusion should only apply to Attributes without a Namespace specified if (a.Namespace.Equals(String.Empty)) { if (RdfXmlSpecsHelper.IsAmbigiousAttributeName(a.LocalName)) { // Can't use any of the RDF terms that mandate the rdf: prefix without it throw new RdfParseException("An Attribute with an ambigious name '" + a.LocalName + "' was encountered. The following attribute names MUST have the rdf: prefix - about, aboutEach, ID, bagID, type, resource, parseType"); } } // URIRef encoding check if (!RdfXmlSpecsHelper.IsValidUriRefEncoding(a.Value)) { throw new RdfParseException("An Attribute with an incorrectly encoded URIRef was encountered, URIRef's must be encoded in Unicode Normal Form C"); } } return(el); }
private void GetQName(Uri u, out String qname, out String ns) { if (this._mapper != null && this._mapper.ReduceToQName(u.ToString(), out qname) && RdfXmlSpecsHelper.IsValidQName(qname)) { //Succesfully reduced to a QName using the known namespaces ns = String.Empty; return; } else if (!u.Fragment.Equals(String.Empty)) { ns = u.ToString().Substring(0, u.ToString().Length - u.Fragment.Length + 1); qname = u.Fragment.Substring(1); } else { #if !SILVERLIGHT qname = u.Segments.LastOrDefault(); #else qname = u.Segments().LastOrDefault(); #endif if (qname == null || !RdfXmlSpecsHelper.IsValidQName(qname)) { throw new RdfOutputException(WriterErrorMessages.UnreducablePropertyURIUnserializable); } ns = u.ToString().Substring(0, u.ToString().Length - qname.Length); } }
private String GenerateUriRef(RdfXmlWriterContext context, Uri u, UriRefType type, out UriRefType outType) { String uriref, qname; if (context.NamespaceMap.ReduceToQName(u.ToString(), out qname) && RdfXmlSpecsHelper.IsValidQName(qname)) { //Reduced to QName OK uriref = qname; outType = UriRefType.QName; } else { //Just use the Uri uriref = u.ToString(); outType = UriRefType.Uri; } //Convert to a Uri Ref from a QName if required if (outType == UriRefType.QName && type == UriRefType.UriRef) { if (uriref.Contains(':') && !uriref.StartsWith(":")) { String prefix = uriref.Substring(0, uriref.IndexOf(':')); if (context.UseDtd && context.NamespaceMap.GetNestingLevel(prefix) == 0) { //Must have Use DTD enabled //Can only use entities for non-temporary Namespaces as Temporary Namespaces won't have Entities defined uriref = "&" + uriref.Replace(':', ';'); outType = UriRefType.UriRef; } else { uriref = context.NamespaceMap.GetNamespaceUri(prefix).ToString() + uriref.Substring(uriref.IndexOf(':') + 1); outType = UriRefType.Uri; } } else { if (context.NamespaceMap.HasNamespace(String.Empty)) { uriref = context.NamespaceMap.GetNamespaceUri(String.Empty).ToString() + uriref.Substring(1); outType = UriRefType.Uri; } else { String baseUri = context.Graph.BaseUri.ToString(); if (!baseUri.EndsWith("#")) { baseUri += "#"; } uriref = baseUri + uriref; outType = UriRefType.Uri; } } //outType = UriRefType.UriRef; } return(uriref); }
private IRdfXmlEvent GetNextAttribute() { _reader.MoveToNextAttribute(); if (IsName("lang", XmlSpecsHelper.NamespaceXml)) { // Generate an event for xml:lang return(new LanguageAttributeEvent(_reader.Value, _reader.Value, GetPosition())); } else if (IsName("base", XmlSpecsHelper.NamespaceXml)) { // Generate an event for xml:base return(new XmlBaseAttributeEvent(_reader.Value, _reader.Value, GetPosition())); } else if (IsInNamespace(XmlSpecsHelper.NamespaceXmlNamespaces)) { // Return a Namespace Attribute Event if (_reader.LocalName.Equals("xmlns")) { return(new NamespaceAttributeEvent(String.Empty, _reader.Value, _reader.Value, GetPosition())); } else { return(new NamespaceAttributeEvent(_reader.LocalName, _reader.Value, _reader.Value, GetPosition())); } } else if (IsInNamespace(XmlSpecsHelper.NamespaceXml) || (_reader.NamespaceURI.Equals(String.Empty) && _reader.Name.StartsWith("xml"))) { // Ignore other XML reserved names return(null); } else if (IsName("parseType", NamespaceMapper.RDF)) { // Support Parse Type by returning an appropriate event switch (_reader.Value) { case "Resource": return(new ParseTypeAttributeEvent(RdfXmlParseType.Resource, _reader.Value, GetPosition())); case "Collection": return(new ParseTypeAttributeEvent(RdfXmlParseType.Collection, _reader.Value, GetPosition())); case "Literal": default: _parseLiteral = true; return(new ParseTypeAttributeEvent(RdfXmlParseType.Literal, _reader.Value, GetPosition())); } } else { if (string.IsNullOrEmpty(_reader.NamespaceURI) && RdfXmlSpecsHelper.IsAmbigiousAttributeName(_reader.LocalName)) { throw new RdfParseException("An Attribute with an ambiguous name '" + _reader.LocalName + "' was encountered. The following attribute names MUST have the rdf: prefix - about, aboutEach, ID, bagID, type, resource, parseType"); } // Normal attribute return(new AttributeEvent(_reader.Name, _reader.Value, _reader.Value, GetPosition())); } }
/// <summary> /// Method which sets the Uri for this Element Event. /// </summary> /// <param name="u">Uri Reference to set Uri from.</param> /// <param name="nsMapper">Namespace prefix mappings to use for resolving the QName of this element event.</param> /// <remarks>This can only be used on Elements which are rdf:li and thus need expanding into actual list elements according to List Expansion rules. Attempting to set the Uri on any other Element Event will cause an Error message.</remarks> public void SetUri(UriReferenceEvent u, INamespaceMapper nsMapper) { if (RdfXmlSpecsHelper.IsLiElement(this, nsMapper)) { // Split the QName into Namespace and Local Name String qname = u.Identifier; String[] parts = qname.Split(':'); _namespace = parts[0]; _localname = parts[1]; } else { throw new RdfParseException("It is forbidden to change the URI of an Element Event unless it is a rdf:li Element and thus needs expanding to the form rdf:_X according to List Expansion rules"); } }
/// <summary> /// Given an XML Node creates the relevant RDF/XML Events for it and recurses as necessary /// </summary> /// <param name="context">Parser Context</param> /// <param name="node">The Node to create Event(s) from</param> /// <param name="parent">The Parent Node of the given Node</param> /// <returns></returns> private ElementEvent GenerateEvents(RdfXmlParserContext context, XmlNode node, IRdfXmlEvent parent) { // Get the Base Uri String baseUri = String.Empty; if (parent is ElementEvent) { baseUri = ((ElementEvent)parent).BaseUri; } // Create an ElementEvent for the Node ElementEvent element = new ElementEvent(node.LocalName, node.Prefix, baseUri, node.OuterXml); // Set the initial Language from the Parent ElementEvent parentEl = (ElementEvent)parent; element.Language = parentEl.Language; #region Attribute Processing // Iterate over Attributes bool parseTypeLiteral = false; foreach (XmlAttribute attr in node.Attributes) { // Watch out for special attributes if (attr.Name == "xml:lang") { // Set Language element.Language = attr.Value; } else if (attr.Name == "xml:base") { // Set Base Uri if (RdfXmlSpecsHelper.IsAbsoluteURI(attr.Value)) { // Absolute Uri element.BaseUri = attr.Value; } else if (!element.BaseUri.Equals(String.Empty)) { // Relative Uri with a Base Uri to resolve against // element.BaseUri += attr.Value; element.BaseUri = Tools.ResolveUri(attr.Value, element.BaseUri); } else { // Relative Uri with no Base Uri throw new RdfParseException("Cannot resolve a Relative Base URI since there is no in-scope Base URI"); } } else if (attr.Prefix == "xmlns") { // Register a Namespace String uri; if (attr.Value.StartsWith("http://")) { // Absolute Uri uri = attr.Value; } else if (!element.BaseUri.Equals(String.Empty)) { // Relative Uri with a Base Uri to resolve against // uri = element.BaseUri + attr.Value; uri = Tools.ResolveUri(attr.Value, element.BaseUri); } else { // Relative Uri with no Base Uri throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI"); } NamespaceAttributeEvent ns = new NamespaceAttributeEvent(attr.LocalName, uri, attr.OuterXml); element.NamespaceAttributes.Add(ns); } else if (attr.Prefix == String.Empty && attr.Name == "xmlns") { // Register a Default Namespace (Empty Prefix) String uri; if (attr.Value.StartsWith("http://")) { // Absolute Uri uri = attr.Value; } else if (!element.BaseUri.Equals(String.Empty)) { // Relative Uri with a Base Uri to resolve against // uri = element.BaseUri + attr.Value; uri = Tools.ResolveUri(attr.Value, element.BaseUri); } else { // Relative Uri with no Base Uri throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI"); } NamespaceAttributeEvent ns = new NamespaceAttributeEvent(String.Empty, uri, attr.OuterXml); element.NamespaceAttributes.Add(ns); } else if (attr.Prefix == "xml" || (attr.Prefix == String.Empty && attr.LocalName.StartsWith("xml"))) { // Ignore other Reserved XML Names } else if (attr.Name == "rdf:parseType" && attr.Value == "Literal") { // Literal Parse Type parseTypeLiteral = true; // Create the Attribute AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml); element.Attributes.Add(attrEvent); // Set ParseType property correctly element.ParseType = RdfXmlParseType.Literal; } else if (attr.Name == "rdf:parseType") { // Some other Parse Type // Create the Attribute AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml); element.Attributes.Add(attrEvent); // Set the ParseType property correctly if (attr.Value == "Resource") { element.ParseType = RdfXmlParseType.Resource; } else if (attr.Value == "Collection") { element.ParseType = RdfXmlParseType.Collection; } else { // Have to assume Literal element.ParseType = RdfXmlParseType.Literal; parseTypeLiteral = true; // Replace the Parse Type attribute with one saying it is Literal element.Attributes.Remove(attrEvent); attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, "Literal", attr.OuterXml); } } else { // Normal Attribute which we generate an Event from AttributeEvent attrEvent = new AttributeEvent(attr.LocalName, attr.Prefix, attr.Value, attr.OuterXml); element.Attributes.Add(attrEvent); } } // Validate generated Attributes for Namespace Confusion and URIRef encoding foreach (AttributeEvent a in element.Attributes) { // Namespace Confusion should only apply to Attributes without a Namespace specified if (a.Namespace.Equals(String.Empty)) { if (RdfXmlSpecsHelper.IsAmbigiousAttributeName(a.LocalName)) { // Can't use any of the RDF terms that mandate the rdf: prefix without it throw ParserHelper.Error("An Attribute with an ambigious name '" + a.LocalName + "' was encountered. The following attribute names MUST have the rdf: prefix - about, aboutEach, ID, bagID, type, resource, parseType", element); } } // URIRef encoding check if (!RdfXmlSpecsHelper.IsValidUriRefEncoding(a.Value)) { throw ParserHelper.Error("An Attribute with an incorrectly encoded URIRef was encountered, URIRef's must be encoded in Unicode Normal Form C", a); } } #endregion // Don't proceed if Literal Parse Type is on if (parseTypeLiteral) { // Generate an XMLLiteral from its Inner Xml (if any) TypedLiteralEvent lit = new TypedLiteralEvent(node.InnerXml.Normalize(), RdfSpecsHelper.RdfXmlLiteral, node.InnerXml); element.Children.Add(lit); return(element); } // Are there Child Nodes? if (node.HasChildNodes) { // Take different actions depending on the Number and Type of Child Nodes if (node.ChildNodes.Count > 1) { // Multiple Child Nodes // Iterate over Child Nodes foreach (XmlNode child in node.ChildNodes) { // Ignore Irrelevant Node Types if (IsIgnorableNode(child)) { continue; } // Generate an Event for the Child Node ElementEvent childEvent = GenerateEvents(context, child, element); element.Children.Add(childEvent); } } else if (node.ChildNodes[0].NodeType == XmlNodeType.Text) { // Single Child which is a Text Node // Generate a Text Event TextEvent text = new TextEvent(node.InnerText.Normalize(), node.OuterXml); element.Children.Add(text); } else if (node.ChildNodes[0].NodeType == XmlNodeType.CDATA) { // Single Child which is a CData Node TextEvent text = new TextEvent(node.InnerXml.Normalize(), node.OuterXml); element.Children.Add(text); } else { // Single Child which is not a Text Node // Recurse on the single Child Node if (!IsIgnorableNode(node.ChildNodes[0])) { ElementEvent childEvent = GenerateEvents(context, node.ChildNodes[0], element); element.Children.Add(childEvent); } } } return(element); }
/// <summary> /// Given an XML Node that is the Root of the RDF/XML section of the Document Tree creates the RootEvent and generates the rest of the Event Tree by recursive calls to the <see cref="GenerateEvents">GenerateEvents</see> method /// </summary> /// <param name="context">Parser Context</param> /// <param name="docEl">XML Node that is the Root of the RDF/XML section of the Document Tree</param> /// <returns></returns> private RootEvent GenerateEventTree(RdfXmlParserContext context, XmlNode docEl) { // Get the Document Element // XmlNode docEl = document.DocumentElement; // Generate a Root Event and Element Event from it RootEvent root = new RootEvent(docEl.BaseURI, docEl.OuterXml); if (docEl.BaseURI.Equals(String.Empty)) { if (context.BaseUri != null) { root.BaseUri = context.BaseUri.AbsoluteUri; } } ElementEvent element = new ElementEvent(docEl.LocalName, docEl.Prefix, root.BaseUri, docEl.OuterXml); // Initialise Language Settings root.Language = String.Empty; element.Language = root.Language; // Set as Document Element and add as only Child root.DocumentElement = element; root.Children.Add(element); #region Attribute Processing // Go through attributes looking for XML Namespace Declarations foreach (XmlAttribute attr in docEl.Attributes) { if (attr.Prefix.Equals("xmlns") || attr.Name == "xmlns") { // Define a Namespace String prefix = attr.LocalName; if (prefix.Equals("xmlns")) { prefix = String.Empty; } String uri; if (attr.Value.StartsWith("http://")) { // Absolute Uri uri = attr.Value; } else if (!root.BaseUri.Equals(String.Empty)) { // Relative Uri with a Base Uri to resolve against // uri = root.BaseUri + attr.Value; uri = Tools.ResolveUri(attr.Value, root.BaseUri); } else { // Relative Uri with no Base Uri throw new RdfParseException("Cannot resolve a Relative Namespace URI since there is no in-scope Base URI"); } context.Namespaces.AddNamespace(prefix, UriFactory.Create(uri)); } else if (attr.Name == "xml:base") { // Set the Base Uri String baseUri = attr.Value; if (RdfXmlSpecsHelper.IsAbsoluteURI(baseUri)) { // Absolute Uri root.BaseUri = baseUri; } else if (!element.BaseUri.Equals(String.Empty)) { // Relative Uri with a Base Uri to resolve against // root.BaseUri += baseUri; root.BaseUri = Tools.ResolveUri(baseUri, root.BaseUri); } else { // Relative Uri with no Base Uri throw new RdfParseException("Cannot resolve a Relative Base URI since there is no in-scope Base URI"); } element.BaseUri = root.BaseUri; } } #endregion // Iterate over Children foreach (XmlNode child in docEl.ChildNodes) { // Ignore Irrelevant Node Types if (IsIgnorableNode(child)) { continue; } // Generate an Event for the Child Node ElementEvent childEvent = GenerateEvents(context, child, element); element.Children.Add(childEvent); } // Return the Root Event return(root); }