/// <summary> /// Loads the file as data from XML data /// </summary> /// <param name="fileDocument">XML document containing the file</param> /// <param name="loadHeaderOnly">if true loads only header information</param> public void Load(XDocument fileDocument,bool loadHeaderOnly) { if (fileDocument == null) { throw new ArgumentNullException("fileDocument"); } if (fileDocument.Root == null) { throw new ArgumentException("Document's root is NULL (empty document passed)"); } // theoretically the namespace should be "http://www.gribuser.ru/xml/fictionbook/2.0" but just to be sure with invalid files _fileNameSpace = fileDocument.Root.GetDefaultNamespace(); _styles.Clear(); IEnumerable<XElement> xStyles = fileDocument.Elements(_fileNameSpace + StyleElement.StyleElementName).ToArray(); // attempt to load some bad FB2 with wrong namespace if (!xStyles.Any()) { xStyles = fileDocument.Elements(StyleElement.StyleElementName); } foreach (var style in xStyles) { var element = new StyleElement(); try { element.Load(style); _styles.Add(element); } catch { // ignored } } LoadDescriptionSection(fileDocument); if (!loadHeaderOnly) { XNamespace namespaceUsed = _fileNameSpace; // Load body elements (first is main text) if (fileDocument.Root != null) { IEnumerable<XElement> xBodys = fileDocument.Root.Elements(_fileNameSpace + Fb2TextBodyElementName).ToArray(); // try to read some badly formatted FB2 files if (!xBodys.Any()) { namespaceUsed = ""; xBodys = fileDocument.Root.Elements(namespaceUsed + Fb2TextBodyElementName); } foreach (var body in xBodys) { var bodyItem = new BodyItem() { NameSpace = namespaceUsed }; try { bodyItem.Load(body); } catch (Exception) { continue; } _bodiesList.Add(bodyItem); } } if (_bodiesList.Count > 0) { _mainBody = _bodiesList[0]; } // Load binaries sections (currently images only) if (fileDocument.Root != null) { IEnumerable<XElement> xBinaryes = fileDocument.Root.Elements(namespaceUsed + Fb2BinaryElementName).ToArray(); if (!xBinaryes.Any()) { xBinaryes = fileDocument.Root.Elements(Fb2BinaryElementName); } foreach (var binarye in xBinaryes) { var item = new BinaryItem(); try { item.Load(binarye); } catch { continue; } // add just unique IDs to fix some invalid FB2s if (!_binaryObjects.ContainsKey(item.Id)) { _binaryObjects.Add(item.Id, item); } } } } }
private void LoadDescriptionSection(XDocument fileDocument, bool loadBinaryItems = true) { if (fileDocument == null) { throw new ArgumentNullException("fileDocument"); } if (fileDocument.Root == null) { throw new NullReferenceException("LoadDescriptionSection: Root is null"); } XElement xTextDescription = fileDocument.Root.Element(_fileNameSpace + Fb2TextDescriptionElementName); // attempt to load some bad FB2 with wrong namespace XNamespace namespaceUsed = _fileNameSpace; if (xTextDescription == null) { namespaceUsed = ""; xTextDescription = fileDocument.Root.Element(Fb2TextDescriptionElementName); } if (xTextDescription != null) { // Load Title info XElement xTitleInfo = xTextDescription.Element(namespaceUsed + TitleInfoElementName); if (xTitleInfo != null) { _titleInfo.Namespace = namespaceUsed; try { _titleInfo.Load(xTitleInfo); } catch (Exception ex) { Debug.WriteLine("Error reading title info : {0}", ex.Message); } } // Load Src Title info XElement xSrcTitleInfo = xTextDescription.Element(namespaceUsed + SrcTitleInfoElementName); if (xSrcTitleInfo != null) { _srcTitleInfo.Namespace = _fileNameSpace; try { _srcTitleInfo.Load(xSrcTitleInfo); } catch (Exception ex) { Debug.WriteLine("Error reading source title info : {0}", ex.Message); } } // Load document info XElement xDocumentInfo = xTextDescription.Element(namespaceUsed + DocumentInfoElementName); if (xDocumentInfo != null) { _documentInfo.Namespace = _fileNameSpace; try { _documentInfo.Load(xDocumentInfo); } catch (Exception ex) { Debug.WriteLine("Error reading document info : {0}", ex.Message); } } // Load publish info XElement xPublishInfo = xTextDescription.Element(namespaceUsed + ItemPublishInfo.PublishInfoElementName); if (xPublishInfo != null) { _publishInfo.Namespace = _fileNameSpace; try { _publishInfo.Load(xPublishInfo); } catch (Exception ex) { Debug.WriteLine("Error reading publishing info : {0}", ex.Message); } } XElement xCustomInfo = xTextDescription.Element(namespaceUsed + ItemCustomInfo.CustomInfoElementName); if (xCustomInfo != null) { var custElement = new ItemCustomInfo {Namespace = _fileNameSpace}; try { custElement.Load(xCustomInfo); _customInfo.Add(custElement); } catch (Exception ex) { Debug.WriteLine("Error reading custom info : {0}", ex.Message); } } IEnumerable<XElement> xInstructions = xTextDescription.Elements(xTextDescription.Name.Namespace + "output"); int outputCount = 0; _output.Clear(); foreach (var xInstruction in xInstructions) { // only two elements allowed by scheme if (outputCount > 1) { break; } var outp = new ShareInstructionType { Namespace = namespaceUsed }; try { outp.Load(xInstruction); _output.Add(outp); } catch (Exception ex) { Debug.WriteLine("Error reading output instructions : {0}", ex); } finally { outputCount++; } } if (loadBinaryItems && _titleInfo.Cover != null) { foreach (InlineImageItem coverImag in _titleInfo.Cover.CoverpageImages) { if (string.IsNullOrEmpty(coverImag.HRef)) { continue; } string coverref = coverImag.HRef.Substring(0, 1) == "#" ? coverImag.HRef.Substring(1) : coverImag.HRef; IEnumerable<XElement> xBinaryes = fileDocument.Root.Elements(_fileNameSpace + Fb2BinaryElementName).Where( cov => ((cov.Attribute("id") != null) && (cov.Attribute("id").Value == coverref))); foreach (var binarye in xBinaryes) { var item = new BinaryItem(); try { item.Load(binarye); } catch (Exception) { continue; } // add just unique IDs to fix some invalid FB2s if (!_binaryObjects.ContainsKey(item.Id)) { _binaryObjects.Add(item.Id, item); } } } } } }