/// <summary> /// This function return the domains attribute that is on the root element of the generalized DTD /// </summary> /// <param name="match">DitaXmlCatalogMatch with the matching generalization catalog entry</param> /// <returns>DtdDomains object</returns> private DtdDomains GetGeneralizedDomainsAttribute(DitaXmlCatalogMatch match) { XmlDocument xml = new XmlDocument(); xml.XmlResolver = _xmlGeneralizedXmlResolver; XmlDocumentType docType = xml.CreateDocumentType(match.GeneralizedRootElement, match.GeneralizedDtdPublicId, match.GeneralizedDtdSystemId, ""); xml.AppendChild(docType); XmlElement rootElement = xml.CreateElement(match.GeneralizedRootElement); xml.AppendChild(rootElement); // FIXED attributes don't seem to be loaded now, therefore we load the xml with the DTD again xml.LoadXml(xml.OuterXml); if (xml.DocumentElement.HasAttribute("domains")) { string domains = xml.DocumentElement.GetAttribute("domains"); xml = null; return(new DtdDomains(domains)); } else { xml = null; throw new InvalidOperationException("No domains attribute found for rootElement=" + match.GeneralizedRootElement + " dtdPublicId=" + match.GeneralizedDtdPublicId + "dtdSystemId=" + match.GeneralizedDtdSystemId); } }
/// <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); }
/// <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); }