コード例 #1
0
ファイル: MarcNodeList.cs プロジェクト: yinjuan1123/chord
        // 对一批互相没有树重叠关系的对象进行筛选
        static MarcNodeList simpleSelect(MarcNodeList source,
                                         string strXPath,
                                         int nMaxCount = -1)
        {
            // 准备一个模拟的记录节点
            // MarcRecord record = new MarcRecord();
            MarcNode temp_root = new MarcNode();

            temp_root.Name = "temp";

            // 保存下集合中所有的Parent指针
            List <MarcNode> parents = new List <MarcNode>();

            foreach (MarcNode node in source)
            {
                // 保存指针
                parents.Add(node.Parent);

                // 建立父子关系,但原来位置的ChidNodes并不摘除
                temp_root.ChildNodes.baseAdd(node);
                node.Parent = temp_root;
                // Debug.Assert(node.Parent == temp_root, "");
            }
            Debug.Assert(parents.Count == source.count, "");

            try
            {
                MarcNodeList results = new MarcNodeList();

                MarcNavigator nav = new MarcNavigator(temp_root);  // 出发点在模拟的记录节点上

                XPathNodeIterator ni = nav.Select(strXPath);
                while (ni.MoveNext() && (nMaxCount == -1 || results.count < nMaxCount))
                {
                    NaviItem item = ((MarcNavigator)ni.Current).Item;
                    if (item.Type != NaviItemType.Element)
                    {
                        throw new Exception("xpath '" + strXPath + "' 命中了非元素类型的节点,这是不允许的");
                        continue;
                    }
                    if (results.indexOf(item.MarcNode) == -1)   // 不重复的才加入
                    {
                        results.add(item.MarcNode);
                    }
                }
                return(results);
            }
            finally
            {
                // 恢复原先的 Parent 指针
                Debug.Assert(parents.Count == source.count, "");
                for (int i = 0; i < source.count; i++)
                {
                    source[i].Parent = parents[i];
                }
            }
        }
コード例 #2
0
ファイル: MarcNodeList.cs プロジェクト: yinjuan1123/chord
        // 针对集合中的元素进行 XPath 筛选
        // 本函数不怕同一批元素之间有重叠关系。所采用的策略是一批一批单独筛选,然后把输出结果合成
        // parameters:
        //      nMaxCount    至多选择开头这么多个元素。-1表示不限制
        /// <summary>
        /// 针对当前集合中的全部元素进行 XPath 选择
        /// </summary>
        /// <param name="strXPath">XPath字符串</param>
        /// <param name="nMaxCount">限制命中的最大元素个数。如果为 -1,表示不限制</param>
        /// <returns>选中的元素所构成的新集合</returns>
        public MarcNodeList select(string strXPath, int nMaxCount /* = -1*/)
        {
            // 把当前集合分割为每段内部确保互相不重叠
            List <MarcNodeList> lists = new List <MarcNodeList>();

            {
                MarcNodeList segment = new MarcNodeList();  // 当前累积的段落
                foreach (MarcNode node in this)
                {
                    if (segment.count > 0)
                    {
                        if (isCross(node, segment) == true)
                        {
                            // 推走
                            lists.Add(segment);
                            segment = new MarcNodeList();
                        }
                    }
                    segment.add(node);
                }

                // 最后剩下的
                if (segment.count > 0)
                {
                    lists.Add(segment);
                }
            }


            MarcNodeList results = new MarcNodeList();

            foreach (MarcNodeList segment in lists)
            {
                // 对一批互相没有树重叠关系的对象进行筛选
                MarcNodeList temp = simpleSelect(segment,
                                                 strXPath,
                                                 -1);
                foreach (MarcNode node in temp)
                {
                    if (results.indexOf(node) == -1)
                    {
                        results.add(node);
                    }
                }

                if (nMaxCount != -1 && results.count >= nMaxCount)
                {
                    if (results.count > nMaxCount)
                    {
                        return(results.getAt(0, nMaxCount));
                    }
                    break;
                }
            }
            return(results);
        }