Example #1
0
        /// <summary>
        /// Determines the generalized element name from the specialized element
        /// To do this, it uses the class attributes of the specialized element and the domains and rootelement of the generalized DTD
        /// </summary>
        /// <param name="xmlReader">XmlReader positioned on an Element node</param>
        /// <param name="xmlGeneralizedConstructionInfo">XmlGeneralizedConstructionInfo with the info of the generalized DTD</param>
        /// <returns>The element name of the generalized element</returns>
        private string GetGeneralizedElement(XmlReader xmlReader, XmlGeneralizedConstructionInfo xmlGeneralizedConstructionInfo)
        {
            string elementNameToInsert = null;
            string classAttribute      = xmlReader.GetAttribute("class");

            if (!String.IsNullOrEmpty(classAttribute))
            {
                DtdClass dtdClass = new DtdClass(classAttribute);

                // Lookup the parts of the specialized class in the list of allowed domains of the generalized DTD
                // We try to match the most specific class part, so we start from the last part (more specific) to the first
                foreach (DtdClassDomainElementPart classPart in dtdClass.DomainElementPartsInReversedOrder)
                {
                    // First check for a domain match. If a domain match is found, we take the matching element name
                    foreach (DtdDomainsPart domainsPart in xmlGeneralizedConstructionInfo.AllowedDomains.DomainsParts)
                    {
                        if (classPart.Domain == domainsPart.DomainName)
                        {
                            elementNameToInsert = classPart.ElementName;
                            break;
                        }
                    }

                    // If found break out of foreach loop, otherwise check with the rootelement e.g. "reference"
                    if (elementNameToInsert != null)
                    {
                        break;
                    }
                    else if (classPart.Domain == xmlGeneralizedConstructionInfo.RootElement)
                    {
                        elementNameToInsert = classPart.ElementName;
                        break;
                    }
                }

                // If we now don't have an element we take the first one of the class string
                if (elementNameToInsert == null)
                {
                    elementNameToInsert = dtdClass.DomainElementParts.First <DtdClassDomainElementPart>().ElementName;
                }
            }
            else
            {
                throw new InvalidOperationException("No class attribute found for element " + xmlReader.Name);
            }

            if (elementNameToInsert == "caption")
            {
                elementNameToInsert = "p";
            }
            return(elementNameToInsert);
        }
Example #2
0
        /// <summary>
        /// Parses the xml at the given file location and tries to lookup the generalized dtd in the generalized-catalog-mapping.xml file.
        /// </summary>
        /// <param name="specializedXmlFileLocation">File location of the specialized xml file</param>
        /// <returns>
        /// If a match is found in the generalized-catalog-mapping.xml file, a XmlGeneralizedConstructionInfo with the necess info (DTD/root element/encoding) to create the generalized xml is returned
        /// If no match is found an InvalidOperationException is raised
        /// </returns>
        private XmlGeneralizedConstructionInfo GetGeneralizedDTD(string specializedXmlFileLocation)
        {
            XmlGeneralizedConstructionInfo xmlGeneralizedConstructionInfo = new XmlGeneralizedConstructionInfo();
            DitaXmlCatalogMatchFilter      filter = new DitaXmlCatalogMatchFilter();

            using (XmlReader xmlReader = XmlReader.Create(specializedXmlFileLocation, InitializeXmlReaderSettings(_xmlSpecializedXmlResolver, ValidationType.None)))
            {
                while (xmlReader.Read())
                {
                    switch (xmlReader.NodeType)
                    {
                    case XmlNodeType.XmlDeclaration:
                        // Get specialized xml encoding
                        if (xmlReader.MoveToAttribute("encoding"))
                        {
                            xmlGeneralizedConstructionInfo.Encoding = Encoding.GetEncoding(xmlReader.Value);
                        }
                        break;

                    case XmlNodeType.DocumentType:
                        // Add specialized DTD info to the filter
                        filter.DtdPublicId = xmlReader.GetAttribute("PUBLIC");
                        filter.DtdSystemId = xmlReader.GetAttribute("SYSTEM");
                        xmlGeneralizedConstructionInfo.DtdInternalSubset = xmlReader.Value;
                        break;

                    case XmlNodeType.Element:
                        // Add specialized root element to the filter
                        filter.RootElement = xmlReader.Name;

                        // try to find a match in the catalog with the found filter parameters
                        DitaXmlCatalogMatch match = _xmlGeneralizationCatalogMapping.GetPreferredMatch(filter);
                        if (match != null)
                        {
                            // A match is found, so copy the found generalized DTD info to the construction info
                            xmlGeneralizedConstructionInfo.DtdPublicId    = match.GeneralizedDtdPublicId;
                            xmlGeneralizedConstructionInfo.DtdSystemId    = match.GeneralizedDtdSystemId;
                            xmlGeneralizedConstructionInfo.RootElement    = match.GeneralizedRootElement;
                            xmlGeneralizedConstructionInfo.AllowedDomains = GetGeneralizedDomainsAttribute(match);

                            return(xmlGeneralizedConstructionInfo);
                        }
                        else
                        {
                            // No match found
                            throw new InvalidOperationException("No matching generalized dtd found for rootElement=" + filter.RootElement + " in dtdPublicId=" + filter.DtdPublicId + "dtdSystemId=" + filter.DtdSystemId);
                        }
                    }
                }
            }
            return(null);
        }
Example #3
0
        /// <summary>
        /// Generalizes the given specialized xml file.
        /// When the generalization succeeds a file is created at the location given in generalizedXmlFileLocation
        /// When the generalization fails a file is created at the location given in errorLogLocation. If this is empty no error file is created.
        /// </summary>
        /// <param name="specializedXmlFileLocation">The location of the specialized xml file</param>
        /// <param name="generalizedXmlFileLocation">The location for the generalized xml file</param>
        /// <returns>true if the generalization succeeded, false if not</returns>
        public void Generalize(FileInfo specializedXmlFileLocation, FileInfo generalizedXmlFileLocation)
        {
            // Validate input Xml
            Validate(specializedXmlFileLocation.FullName, InitializeXmlReaderSettings(_xmlSpecializedXmlResolver, ValidationType.DTD));

            // Get the corresponding generalized DTD info for the DTD/root element of the specialized input Xml
            XmlGeneralizedConstructionInfo xmlGeneralizedConstructionInfo = GetGeneralizedDTD(specializedXmlFileLocation.FullName);

            // Loop over the specialized xml and generalize elements and attributes (non validating)
            using (XmlWriter xmlWriter = XmlWriter.Create(generalizedXmlFileLocation.FullName, InitializeXmlWriterSettings(xmlGeneralizedConstructionInfo.Encoding)))
            {
                using (XmlReader xmlReader = XmlReader.Create(specializedXmlFileLocation.FullName, InitializeXmlReaderSettings(_xmlSpecializedXmlResolver, ValidationType.None)))
                {
                    bool   rootElementEncountered = false;
                    string previousElementName    = "";

                    xmlReader.Read();
                    while (!xmlReader.EOF)
                    {
                        string currElementName = xmlReader.Name;

                        switch (xmlReader.NodeType)
                        {
                        case XmlNodeType.DocumentType:
                            // Write generalized DTD
                            xmlWriter.WriteDocType(xmlGeneralizedConstructionInfo.RootElement, xmlGeneralizedConstructionInfo.DtdPublicId, xmlGeneralizedConstructionInfo.DtdSystemId, xmlGeneralizedConstructionInfo.DtdInternalSubset);
                            xmlReader.Read();
                            break;

                        case XmlNodeType.Element:
                            string elementNameToInsert = null;
                            if (!rootElementEncountered)
                            {
                                // Since this is the root element, use the root element of the generalized DTD
                                elementNameToInsert    = xmlGeneralizedConstructionInfo.RootElement;
                                rootElementEncountered = true;
                            }
                            else
                            {
                                // Determine generalized element name
                                elementNameToInsert = GetGeneralizedElement(xmlReader, xmlGeneralizedConstructionInfo);
                            }

                            // Write generalized element and attributes to the writer
                            if (xmlReader.IsEmptyElement)
                            {
                                xmlWriter.WriteStartElement(elementNameToInsert);
                                WriteGeneralizedAttributes(xmlReader, xmlWriter);
                                xmlWriter.WriteEndElement();
                            }
                            else
                            {
                                xmlWriter.WriteStartElement(elementNameToInsert);
                                WriteGeneralizedAttributes(xmlReader, xmlWriter);
                            }
                            previousElementName = elementNameToInsert;

                            xmlReader.Read();

                            break;

                        case XmlNodeType.EndElement:
                            // Write element close. (WriteNode might not work)
                            xmlWriter.WriteEndElement();

                            xmlReader.Read();
                            break;

                        default:
                            // Just write all other nodes to the writer without any conversion
                            xmlWriter.WriteNode(xmlReader, false);
                            break;
                        }
                    }
                }
            }

            // Validate generalized result Xml
            Validate(generalizedXmlFileLocation.FullName, InitializeXmlReaderSettings(_xmlGeneralizedXmlResolver, ValidationType.DTD));
        }