/// <summary>
        /// Searches for all matches on the specified filter criterea and returns the preferred match.
        /// The preferred match is found as follows:
        /// First we try to find a match entry where the dtdpublicid + dtdsystemid + rootelement all match -> if we find matches, the first one is returned
        /// Second we try to find a match entry where the dtdpublicid + rootelement both match -> if we find matches, the first one is returned
        /// Third we try to find a match entry where the dtdsystemid + rootelement both match -> if we find matches, the first one is returned
        /// Last we try to find a match entry where the rootelement matches -> if we find matches, the first one is returned
        /// </summary>
        /// <param name="filter">filter criterea to search on</param>
        /// <returns>The preferred match</returns>
        public DitaXmlCatalogMatch GetPreferredMatch(DitaXmlCatalogMatchFilter filter)
        {
            DitaXmlCatalogMatch match = null;

            if (!String.IsNullOrEmpty(filter.DtdPublicId) && !String.IsNullOrEmpty(filter.DtdSystemId) && !String.IsNullOrEmpty(filter.RootElement))
            {
                match = FindFirstFilterMatch(x => x.DtdPublicId == filter.DtdPublicId && x.DtdSystemId == filter.DtdSystemId && x.RootElement == filter.RootElement, filter.IgnoreMatchesWithMissingGeneralizedDTDInfo);
            }

            if (match == null && !String.IsNullOrEmpty(filter.DtdPublicId) && !String.IsNullOrEmpty(filter.RootElement))
            {
                match = FindFirstFilterMatch(x => x.DtdPublicId == filter.DtdPublicId && x.RootElement == filter.RootElement, filter.IgnoreMatchesWithMissingGeneralizedDTDInfo);
            }

            if (match == null && !String.IsNullOrEmpty(filter.DtdSystemId) && !String.IsNullOrEmpty(filter.RootElement))
            {
                match = FindFirstFilterMatch(x => x.DtdSystemId == filter.DtdSystemId && x.RootElement == filter.RootElement, filter.IgnoreMatchesWithMissingGeneralizedDTDInfo);
            }

            if (match == null && !String.IsNullOrEmpty(filter.RootElement))
            {
                match = FindFirstFilterMatch(x => x.RootElement == filter.RootElement, filter.IgnoreMatchesWithMissingGeneralizedDTDInfo);
            }

            if (match != null)
            {
                return(match);
            }
            return(null);
        }
Пример #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);
        }