SobekCM.Resource_Object.Metadata_File_ReaderWriters.METS_File_ReaderWriter.read_struct_map C# (CSharp) Method

read_struct_map() private static method

private static read_struct_map ( XmlReader R, SobekCM_Item Package, SobekCM_File_Info>.Dictionary FilesByFileid, abstract_TreeNode>.Dictionary DivisionDmdids, abstract_TreeNode>.Dictionary DivisionAmdids ) : void
R XmlReader
Package SobekCM_Item
FilesByFileid SobekCM_File_Info>.Dictionary
DivisionDmdids abstract_TreeNode>.Dictionary
DivisionAmdids abstract_TreeNode>.Dictionary
return void
        private static void read_struct_map(XmlReader R, SobekCM_Item Package, Dictionary<string, SobekCM_File_Info> FilesByFileid, Dictionary<string, abstract_TreeNode> DivisionDmdids, Dictionary<string, abstract_TreeNode> DivisionAmdids )
        {
            Stack<abstract_TreeNode> parentNodes = new Stack<abstract_TreeNode>();
            Dictionary<string, abstract_TreeNode> divisions_by_id = new Dictionary<string, abstract_TreeNode>();

            bool mainDivisionFound = false;
            Division_Tree thisDivTree = null;

            // Loop through reading each XML node
            do
            {
                // get the right division information based on node type
                switch (R.NodeType)
                {
                        // if EndElement, move up tree
                    case XmlNodeType.EndElement:
                        if ((R.Name == "METS:structMap") || ( R.Name == "structMap" ))
                        {
                            return;
                        }

                        if ((R.Name == "METS:div") || (R.Name == "div"))
                        {
                            // If there are more than one parent on the "parent stack" pop one off
                            if (parentNodes.Count > 0)
                                parentNodes.Pop();
                        }
                        break;

                        // if new element, add name and traverse tree
                    case XmlNodeType.Element:

                        // Is this the beginning of a structure map
                        if ((R.Name == "METS:structMap") || (R.Name == "structMap"))
                        {
                            thisDivTree = Package.Divisions.Physical_Tree;
                            if (R.MoveToAttribute("TYPE"))
                            {
                                if (R.Value.ToUpper() == "OTHER")
                                    thisDivTree = Package.Divisions.Download_Tree;
                            }
                        }

                        // Is this a new division?
                        if (((R.Name == "METS:div") || ( R.Name == "div" )) && (R.HasAttributes))
                        {
                            // Since this is a new division, get all the possible attribute values or set to empty string
                            string dmdid = (R.MoveToAttribute("DMDID") ? R.Value : String.Empty);
                            string amdid = (R.MoveToAttribute("AMDID") ? R.Value : String.Empty);
                            string divID = (R.MoveToAttribute("DMDID") ? R.Value : String.Empty);
                            string divType = (R.MoveToAttribute("TYPE") ? R.Value : String.Empty);
                            string divLabel = (R.MoveToAttribute("LABEL") ? R.Value : String.Empty);

                            // Get the order
                            ushort divOrder;
                            if (R.MoveToAttribute("ORDER"))
                            {
                                if (!UInt16.TryParse(R.Value, out divOrder)) divOrder = 0;
                            }
                            else if (R.MoveToAttribute("ORDERLABEL"))
                            {
                                if (!UInt16.TryParse(R.Value, out divOrder)) divOrder = 0;
                            }
                            else
                            {
                                divOrder = 0;
                            }

                            // Was this an outer division, or the main division?
                            if (!mainDivisionFound) 
                            {
                                // This is an outer wrapper and NOT the MAIN division, so save this as an
                                // outer division (division greater than current digital resources), such as 
                                // used sometimes for serials or journals.
                                if (divType.ToUpper() != "MAIN")
                                {
                                    if (!Package.Divisions.Contains_Outer_Division(divLabel, divType))
                                    {
                                        Package.Divisions.Add_Outer_Division(divLabel, divOrder, divType);
                                    }
                                }
                                else
                                {
                                    mainDivisionFound = true;
                                }
                            }
                            else
                            {
                                // Get the parent node, if there is one
                                abstract_TreeNode parentNode = parentNodes.Count > 0 ? parentNodes.Peek() : null;

                                // Create this division
                                abstract_TreeNode bibNode;
                                if (divType.ToUpper() == "PAGE")
                                    bibNode = new Page_TreeNode(divLabel);
                                else
                                    bibNode = new Division_TreeNode(divType, divLabel);

                                // Check to make sure no repeat here                               
                                if (divID.IndexOf("_repeat") > 0)
                                {
                                    divID = divID.Substring(0, divID.IndexOf("_repeat"));
                                    if (divisions_by_id.ContainsKey(divID))
                                    {
                                        bibNode = divisions_by_id[divID];
                                    }
                                }
                                
                                // Get the DMD sec or AMD sec's 
                                if (dmdid.Length > 0)
                                {
                                    string[] divDmdSecIds = dmdid.Split(" ".ToCharArray());
                                    foreach( string thisId in divDmdSecIds )
                                    {
                                        DivisionDmdids[thisId] = bibNode;
                                    }                                        
                                }
                                if (amdid.Length > 0)
                                {
                                    string[] divAmdSecIds = amdid.Split(" ".ToCharArray());
                                    foreach (string thisId in divAmdSecIds)
                                    {
                                        DivisionAmdids[thisId] = bibNode;
                                    }
                                }

                                // If there is a parent, add to it
                                if (parentNode != null)
                                {
                                    ((Division_TreeNode) parentNode).Nodes.Add(bibNode);
                                }
                                else
                                {
                                    // No parent, so add this to the root
                                    thisDivTree.Roots.Add(bibNode);
                                }

                                // Now, add this to the end of the parent list, in case it has children
                                if (!R.IsEmptyElement)
                                {
                                    parentNodes.Push(bibNode);
                                }
                            }

                            R.MoveToElement();
                        }

                        // Is this a new file pointer applying to the last division?
                        if (((R.Name == "METS:fptr") || (R.Name == "fptr")) && (R.MoveToAttribute("FILEID")))
                        {
                            // Get this file id
                            string fileID = R.Value;

                            // Get the file from the files by id dictionary
                            if (FilesByFileid.ContainsKey(fileID))
                            {
                                SobekCM_File_Info thisFile = FilesByFileid[fileID];

                                abstract_TreeNode pageParentNode = null;
                                if (parentNodes.Count > 0)
                                    pageParentNode = parentNodes.Peek();


                                if ((pageParentNode != null) && (pageParentNode.Page))
                                {
                                    Page_TreeNode asPageNode = (Page_TreeNode) pageParentNode;
                                    if (!asPageNode.Files.Contains(thisFile))
                                        asPageNode.Files.Add(thisFile);
                                }
                                else
                                {
                                    if (pageParentNode == null)
                                    {
                                        thisDivTree.Add_File(thisFile);
                                    }
                                    else
                                    {
                                        Division_TreeNode asDivNode = (Division_TreeNode) pageParentNode;

                                        Page_TreeNode newPage = new Page_TreeNode();
                                        asDivNode.Add_Child(newPage);

                                        //parentNodes.Push(newPage);

                                        newPage.Files.Add(thisFile);
                                    }
                                }
                            }
                        }

                        // Is this a new METS pointer, often seen when importing from DSpace
                        if ((R.Name == "METS:mptr") || (R.Name == "mptr")) 
                        {
                            // Get the parent label
                            string parentLabel = String.Empty;

                            // Look for a parent node (should be one)
                            if (parentNodes.Count > 0)
                            {
                                abstract_TreeNode pageParentNode = parentNodes.Peek();
                                parentLabel = pageParentNode.Label;
                            }
                            else if (Package.Divisions.Outer_Division_Count > 0)
                            {
                                parentLabel = Package.Divisions.Outer_Divisions[Package.Divisions.Outer_Division_Count - 1].Label;
                            }

                            if ((!String.IsNullOrEmpty(parentLabel)) && (String.Compare(parentLabel, "Parent of this DSpace Object", StringComparison.OrdinalIgnoreCase) == 0))
                            {
                                // Is this a HANDLE reference?
                                string locType = (R.MoveToAttribute("LOCTYPE") ? R.Value : String.Empty).ToUpper();
                                string href = (R.MoveToAttribute("xlink:href") ? R.Value : String.Empty);

                                // If this has a handle href, make that the aggregation
                                if ((locType == "HANDLE") && (href.Length > 0))
                                {
                                    Package.Behaviors.Add_Aggregation(href);
                                }
                            }
                        }

                        break;

                } // end switch
            } while (R.Read());
        }