private static async Task<EpubNavigationPoint> ReadNavigationPointAsync(XmlReader reader)
        {
            EpubNavigationPoint result = new EpubNavigationPoint();
            //we have to skip first entry as it could be empty after new sub-reader created
            if (reader.NodeType == XmlNodeType.None) await reader.ReadAsync();
            //Now the pointer should point to the <navPoint> itself
            while (reader.MoveToNextAttribute()) //Doing this we just passing through <navPoint> tag
            {
                switch (reader.LocalName.ToLowerInvariant()) //We have to collect all possible attributes from the <navPoint>
                {
                    case "id":
                        result.Id = reader.Value;
                        break;
                    case "class":
                        result.Class = reader.Value;
                        break;
                    case "playorder":
                        result.PlayOrder = reader.Value;
                        break;
                }
            }
            if (String.IsNullOrWhiteSpace(result.Id))
                throw new Exception("Incorrect EPUB navigation point: point ID is missing");

            result.NavigationLabels = new List<EpubNavigationLabel>();
            result.ChildNavigationPoints = new List<EpubNavigationPoint>();
            // We need to make sure that we will return pointer back to <navPoint> entry after reading all attributes
            reader.MoveToElement();
            //Now we are looking for subnodes - navLabel, content and sub-navPoints
            while (await reader.ReadAsync())
            {
                if (reader.NodeType != XmlNodeType.EndElement)
                    switch (reader.LocalName.ToLowerInvariant())
                    {
                        case "navlabel":
                            EpubNavigationLabel navigationLabel = await ReadNavigationLabelAsync(reader);// Adding label to collection
                            result.NavigationLabels.Add(navigationLabel);
                            break;
                        case "content":
                            EpubNavigationContent content = await ReadNavigationContentAsync(reader); //Adding content to collection
                            result.Content = content;
                            break;
                        case "navpoint": //Yeep. Looks like we found a <navPoint> sub-node
                            XmlReader subTree = reader.ReadSubtree(); //Cooking a separate sub-reader scope for this node to separate it from the others siblings
                            EpubNavigationPoint childNavigationPoint = await ReadNavigationPointAsync(subTree);// I hate recursion...
                            //Adding a child to a collection
                            result.ChildNavigationPoints.Add(childNavigationPoint);
                            subTree.Dispose();
                            break;
                    }
            };

            return result;
        }
Example #2
0
 private static EpubNavigationPoint ReadNavigationPoint(XmlNode navigationPointNode)
 {
     EpubNavigationPoint result = new EpubNavigationPoint();
     foreach (XmlAttribute navigationPointNodeAttribute in navigationPointNode.Attributes)
     {
         string attributeValue = navigationPointNodeAttribute.Value;
         switch (navigationPointNodeAttribute.Name.ToLowerInvariant())
         {
             case "id":
                 result.Id = attributeValue;
                 break;
             case "class":
                 result.Class = attributeValue;
                 break;
             case "playOrder":
                 result.PlayOrder = attributeValue;
                 break;
         }
     }
     if (String.IsNullOrWhiteSpace(result.Id))
         throw new Exception("Incorrect EPUB navigation point: point ID is missing");
     result.NavigationLabels = new List<EpubNavigationLabel>();
     result.ChildNavigationPoints = new List<EpubNavigationPoint>();
     foreach (XmlNode navigationPointChildNode in navigationPointNode.ChildNodes)
         switch (navigationPointChildNode.LocalName.ToLowerInvariant())
         {
             case "navlabel":
                 EpubNavigationLabel navigationLabel = ReadNavigationLabel(navigationPointChildNode);
                 result.NavigationLabels.Add(navigationLabel);
                 break;
             case "content":
                 EpubNavigationContent content = ReadNavigationContent(navigationPointChildNode);
                 result.Content = content;
                 break;
             case "navpoint":
                 EpubNavigationPoint childNavigationPoint = ReadNavigationPoint(navigationPointChildNode);
                 result.ChildNavigationPoints.Add(childNavigationPoint);
                 break;
         }
     if (!result.NavigationLabels.Any())
         throw new Exception(String.Format("EPUB parsing error: navigation point {0} should contain at least one navigation label", result.Id));
     if (result.Content == null)
         throw new Exception(String.Format("EPUB parsing error: navigation point {0} should contain content", result.Id));
     return result;
 }