예제 #1
0
        private void WriteXmlStartTagsForPackageProperties()
        {
            _xmlWriter.WriteStartDocument();

            // <coreProperties
            _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(PackageXmlEnum.CoreProperties),                  // local name
                                         PackageXmlStringTable.GetXmlString(PackageXmlEnum.PackageCorePropertiesNamespace)); // namespace

            // xmlns:dc
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCorePropertiesNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCorePropertiesNamespace));

            // xmlns:dcterms
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublincCoreTermsNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));
            // xmlns:xsi
            _xmlWriter.WriteAttributeString(PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlNamespacePrefix),
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespacePrefix),
                                            null,
                                            PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));
        }
예제 #2
0
        // This method validates xsi:type="dcterms:W3CDTF"
        // The valude of xsi:type is a qualified name. It should have a prefix that matches
        //  the xml namespace (ns) within the scope and the name that matches name
        // The comparisons should be case-sensitive comparisons
        internal static void ValidateXsiType(XmlTextReader reader, Object ns, string name)
        {
            // Get the value of xsi;type
            String typeValue = reader.GetAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                   PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

            // Missing xsi:type
            if (typeValue == null)
            {
                throw new XmlException(SR.Get(SRID.UnknownDCDateTimeXsiType, reader.Name),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            int index = typeValue.IndexOf(':');

            // The valude of xsi:type is not a qualified name
            if (index == -1)
            {
                throw new XmlException(SR.Get(SRID.UnknownDCDateTimeXsiType, reader.Name),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            // Check the following conditions
            //  The namespace of the prefix (string before ":") matches "ns"
            //  The name (string after ":") matches "name"
            if (!Object.ReferenceEquals(ns, reader.LookupNamespace(typeValue.Substring(0, index))) ||
                String.CompareOrdinal(name, typeValue.Substring(index + 1, typeValue.Length - index - 1)) != 0)
            {
                throw new XmlException(SR.Get(SRID.UnknownDCDateTimeXsiType, reader.Name),
                                       null, reader.LineNumber, reader.LinePosition);
            }
        }
예제 #3
0
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        #region Constructors

        internal PartBasedPackageProperties(Package package)
        {
            _package = package;

            // Initialize literals as Xml Atomic strings.
            // We use a clone of the name table so that different threads don't
            // change the same table concurrently (Dev11 880952)
            _nameTable = PackageXmlStringTable.CloneNameTable();

            ReadPropertyValuesFromPackage();

            // No matter what happens during initialization, the dirty flag should not be set.
            _dirty = false;
        }
예제 #4
0
 internal static string GetValueType(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].ValueType);
 }
예제 #5
0
 internal static PackageXmlEnum GetXmlNamespace(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].Namespace);
 }
예제 #6
0
 internal static object GetXmlStringAsObject(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].Name);
 }
예제 #7
0
 internal static string GetXmlString(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return((string)PackageXmlStringTable._xmlstringtable[(int)id].Name);
 }
예제 #8
0
        // Write the property elements and clear _dirty.
        private void SerializeDirtyProperties()
        {
            // In streaming mode, nullify dictionary values.
            // As no property can be set to null through the API, this makes it possible to keep
            // track of all properties that have been set since the CoreProperties object was created.
            KeyValuePair <PackageXmlEnum, Object>[] entriesToNullify = null;
            int numEntriesToNullify = 0;

            if (_package.InStreamingCreation)
            {
                entriesToNullify = new KeyValuePair <PackageXmlEnum, Object> [_propertyDictionary.Count];
            }

            // Create a property element for each non-null entry.
            foreach (KeyValuePair <PackageXmlEnum, Object> entry in _propertyDictionary)
            {
                // If we are NOT in streaming mode, the property value should NOT be null
                Debug.Assert(entry.Value != null || _package.InStreamingCreation);

                if (_package.InStreamingCreation &&
                    entry.Value == null)    // already saved
                {
                    continue;
                }


                PackageXmlEnum propertyNamespace = PackageXmlStringTable.GetXmlNamespace(entry.Key);

                _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(entry.Key),
                                             PackageXmlStringTable.GetXmlString(propertyNamespace));

                if (entry.Value is Nullable <DateTime> )
                {
                    if (propertyNamespace == PackageXmlEnum.DublinCoreTermsNamespace)
                    {
                        // xsi:type=
                        _xmlWriter.WriteStartAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                       PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

                        // "dcterms:W3CDTF"
                        _xmlWriter.WriteQualifiedName(_w3cdtf,
                                                      PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));

                        _xmlWriter.WriteEndAttribute();
                    }

                    // Use sortable ISO 8601 date/time pattern. Include second fractions down to the 100-nanosecond interval,
                    // which is the definition of a "tick" for the DateTime type.
                    _xmlWriter.WriteString(XmlConvert.ToString(((Nullable <DateTime>)entry.Value).Value.ToUniversalTime(), "yyyy-MM-ddTHH:mm:ss.fffffffZ"));
                }
                else
                {
                    // The following uses the fact that ToString is virtual.
                    _xmlWriter.WriteString(entry.Value.ToString());
                }

                _xmlWriter.WriteEndElement();

                if (_package.InStreamingCreation)
                {
                    entriesToNullify[numEntriesToNullify++] = entry;
                }
            }

            // Mark properties as saved.
            _dirty = false;

            // Detailed marking of saved properties for the streaming mode.
            if (_package.InStreamingCreation)
            {
                for (int i = 0; i < numEntriesToNullify; ++i)
                {
                    _propertyDictionary[entriesToNullify[i].Key] = null;
                }
            }
        }
예제 #9
0
        // Deserialize properties part.
        private void ParseCorePropertyPart(PackagePart part)
        {
            Stream stream = part.GetStream(FileMode.Open, FileAccess.Read);

            // Create a reader that uses _nameTable so as to use the set of tag literals
            // in effect as a set of atomic identifiers.
            XmlTextReader reader = new XmlTextReader(stream, _nameTable);

            //Prohibit DTD from the markup as per the OPC spec
            reader.ProhibitDtd = true;

            //This method expects the reader to be in ReadState.Initial.
            //It will make the first read call.
            PackagingUtilities.PerformInitailReadAndVerifyEncoding(reader);

            //Note: After the previous method call the reader should be at the first tag in the markup.
            //MoveToContent - Skips over the following - ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace
            //If the reader is currently at a content node then this function call is a no-op
            if (reader.MoveToContent() != XmlNodeType.Element ||
                (object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.PackageCorePropertiesNamespace) ||
                (object)reader.LocalName != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.CoreProperties))
            {
                throw new XmlException(SR.Get(SRID.CorePropertiesElementExpected),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            // The schema is closed and defines no attributes on the root element.
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) != 0)
            {
                throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                       null, reader.LineNumber, reader.LinePosition);
            }

            // Iterate through property elements until EOF. Note the proper closing of all
            // open tags is checked by the reader itself.
            // This loop deals only with depth-1 start tags. Handling of element content
            // is delegated to dedicated functions.
            int attributesCount;

            while (reader.Read() && reader.MoveToContent() != XmlNodeType.None)
            {
                // Ignore end-tags. We check element errors on opening tags.
                if (reader.NodeType == XmlNodeType.EndElement)
                {
                    continue;
                }

                // Any content markup that is not an element here is unexpected.
                if (reader.NodeType != XmlNodeType.Element)
                {
                    throw new XmlException(SR.Get(SRID.PropertyStartTagExpected),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                // Any element below the root should open at level 1 exclusively.
                if (reader.Depth != 1)
                {
                    throw new XmlException(SR.Get(SRID.NoStructuredContentInsideProperties),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                attributesCount = PackagingUtilities.GetNonXmlnsAttributeCount(reader);

                // Property elements can occur in any order (xsd:all).
                object         localName      = reader.LocalName;
                PackageXmlEnum xmlStringIndex = PackageXmlStringTable.GetEnumOf(localName);
                String         valueType      = PackageXmlStringTable.GetValueType(xmlStringIndex);

                if (Array.IndexOf(_validProperties, xmlStringIndex) == -1)  // An unexpected element is an error.
                {
                    throw new XmlException(
                              SR.Get(SRID.InvalidPropertyNameInCorePropertiesPart, reader.LocalName),
                              null, reader.LineNumber, reader.LinePosition);
                }

                // Any element not in the valid core properties namespace is unexpected.
                // The following is an object comparison, not a string comparison.
                if ((object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlStringTable.GetXmlNamespace(xmlStringIndex)))
                {
                    throw new XmlException(SR.Get(SRID.UnknownNamespaceInCorePropertiesPart),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                if (String.CompareOrdinal(valueType, "String") == 0)
                {
                    // The schema is closed and defines no attributes on this type of element.
                    if (attributesCount != 0)
                    {
                        throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                               null, reader.LineNumber, reader.LinePosition);
                    }

                    RecordNewBinding(xmlStringIndex, GetStringData(reader), true /*initializing*/, reader);
                }
                else if (String.CompareOrdinal(valueType, "DateTime") == 0)
                {
                    int allowedAttributeCount = (object)reader.NamespaceURI ==
                                                PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace)
                                                    ? 1 : 0;

                    // The schema is closed and defines no attributes on this type of element.
                    if (attributesCount != allowedAttributeCount)
                    {
                        throw new XmlException(SR.Get(SRID.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                               null, reader.LineNumber, reader.LinePosition);
                    }

                    if (allowedAttributeCount != 0)
                    {
                        ValidateXsiType(reader,
                                        PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace),
                                        _w3cdtf);
                    }

                    RecordNewBinding(xmlStringIndex, GetDateData(reader), true /*initializing*/, reader);
                }
                else  // An unexpected element is an error.
                {
                    Invariant.Assert(false, "Unknown value type for properties");
                }
            }
        }