Example #1
0
        // 根据字段权限定义过滤出允许的内容
        // return:
        //      -1  出错
        //      0   成功
        //      1   有部分字段被修改或滤除
        public static int FilterFields(string strFieldNameList,
            ref string strMarc,
            out string strError)
        {
            strError = "";
            int nRet = 0;
            bool bChanged = false;

            if (string.IsNullOrEmpty(strMarc) == true)
                return 0;

            string strHeader = "";
            string strBody = "";

            SplitMarc(strMarc,
                out strHeader,
                out strBody);

            if (strHeader.Length < 24)
            {
                strHeader = strHeader.PadRight(24, '?');
                bChanged = true;
            }

            FieldNameList list = new FieldNameList();
            nRet = list.Build(strFieldNameList, out strError);
            if (nRet == -1)
            {
                strError = "字段权限定义 '"+strFieldNameList+"' 不合法: " + strError;
                return -1;
            }

            StringBuilder text = new StringBuilder(4096);
            if (list.Contains("###") == true)
                text.Append(strHeader);
            else
            {
                bChanged = true;
                text.Append(new string('?', 24));
            }

            string[] fields = strBody.Split(new char[] {(char)30}, StringSplitOptions.RemoveEmptyEntries);
            foreach (string s in fields)
            {
                if (string.IsNullOrEmpty(s) == true)
                    continue;

                string strFieldName = GetFieldName(s);
                if (list.Contains(strFieldName) == false)
                {
                    bChanged = true;
                    continue;
                }

                text.Append(s);
                text.Append((char)30);
            }

            strMarc = text.ToString();
            if (bChanged == true)
                return 1;
            return 0;
        }
Example #2
0
        // 根据允许的字段名列表,合并新旧两条书目记录
        // 列表中不允许的字段,沿用旧记录中的原始字段内容
        // 算法等于在 new 中复原了那些不让修改的 MARC 字段
        static int MergeOldNewBiblioByFieldNameList(
            string strFieldNameList,
            string strOldBiblioXml,
            ref string strNewBiblioXml,
            out string strError)
        {
            strError = "";
            int nRet = 0;

            XmlDocument domNew = new XmlDocument();
            if (String.IsNullOrEmpty(strNewBiblioXml) == true)
                strNewBiblioXml = "<root />";
            try
            {
                domNew.LoadXml(strNewBiblioXml);
            }
            catch (Exception ex)
            {
                strError = "strNewBiblioXml装入XMLDOM时出错: " + ex.Message;
                return -1;
            }

            string strNewSave = domNew.OuterXml;

            XmlDocument domOld = new XmlDocument();
            if (String.IsNullOrEmpty(strOldBiblioXml) == true
                || (string.IsNullOrEmpty(strOldBiblioXml) == false && strOldBiblioXml.Length == 1))
                strOldBiblioXml = "<root />";
            try
            {
                domOld.LoadXml(strOldBiblioXml);
            }
            catch (Exception ex)
            {
                strError = "strOldBiblioXml装入XMLDOM时出错: " + ex.Message;
                return -1;
            }

            string strMarcSyntax = "";

            // 探测MARC格式
            // return:
            //      -1  error
            //      0   无法探测
            //      1   探测到了
            nRet = DetectMarcSyntax(domNew,
            out strMarcSyntax,
            out strError);
            if (nRet == -1)
                return -1;
            if (nRet == 0)
            {
                nRet = DetectMarcSyntax(domOld,
out strMarcSyntax,
out strError);
                if (nRet == -1)
                    return -1;
                if (nRet == 0)
                {
                    strError = "无法探测到 MARC 格式";
                    return -1;
                }
            }

            FieldNameList list = new FieldNameList();
            nRet = list.Build(strFieldNameList, out strError);
            if (nRet == -1)
                return -1;

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
            nsmgr.AddNamespace("unimarc", Ns.unimarcxml);
            nsmgr.AddNamespace("usmarc", Ns.usmarcxml);

            XmlNode old_root = domOld.DocumentElement.SelectSingleNode("//" + strMarcSyntax + ":record", nsmgr);
            if (old_root == null)
            {
                // 对 new 过滤出全部可以修改的字段即可
                XmlNodeList new_nodes = domNew.DocumentElement.SelectNodes("//" + strMarcSyntax + ":leader | //" + strMarcSyntax + ":controlfield | //" + strMarcSyntax + ":datafield",
nsmgr);
                foreach (XmlNode node in new_nodes)
                {
                    XmlElement element = (XmlElement)node;
                    string strTag = GetTag(element);

                    // TODO:如果连头标区也要滤除,要保留一个缺省值的头标区
                    if (list.Contains(strTag) == false && strTag != "###")
                        node.ParentNode.RemoveChild(node);

                }
                strNewBiblioXml = domNew.DocumentElement.OuterXml;
                return 0;
            }

            XmlNode new_root = domNew.DocumentElement.SelectSingleNode("//" + strMarcSyntax + ":record", nsmgr);
            if (new_root == null)
            {
                // new 里面没有任何 MARC 字段,因此不必作了
                return 0;
            }

            // 1) 把 new 中的 不允许修改的字段标记出来
            List<XmlNode> reserve_nodes = new List<XmlNode>();
            {
                XmlNodeList new_nodes = domNew.DocumentElement.SelectNodes("//" + strMarcSyntax + ":leader | //" + strMarcSyntax + ":controlfield | //" + strMarcSyntax + ":datafield",
                    nsmgr);
                foreach (XmlNode node in new_nodes)
                {
                    XmlElement element = (XmlElement)node;
                    string strTag = GetTag(element);

                    if (list.Contains(strTag) == false)
                        reserve_nodes.Add(element);
                }
            }

            // 2) 从 old 中把全部不允许修改的字段对应位置一个一个覆盖 new 中的对应字段。如果在 new 中没有找到对应字段,在插入在最后一个同名字段后面,如果没有同名字段,则插入到适当的顺序位置
            XmlNodeList old_nodes = domOld.DocumentElement.SelectNodes("//" + strMarcSyntax + ":leader | //" + strMarcSyntax + ":controlfield | //" + strMarcSyntax + ":datafield",
    nsmgr);
            foreach (XmlNode node in old_nodes)
            {
                XmlElement element = (XmlElement)node;
                string strTag = GetTag(element);

                if (list.Contains(strTag) == true)
                    continue;

                XmlElement last_same_name_node = null;
                // 在另一边(nodes内)寻找对应的字段元素
                // parameters:
                //      last_same_name_node 最后一个同tag名的元素
                XmlElement target = FindElement(element,
                    new_root,
                    out last_same_name_node);
                if (target != null)
                {
                    target.InnerXml = element.InnerXml;
                    if (target.LocalName == "datafield")
                    {
                        // 还要修改 ind1 ind2 属性
                        target.SetAttribute("ind1", element.GetAttribute("ind1"));
                        target.SetAttribute("ind2", element.GetAttribute("ind2"));
                    }
                    reserve_nodes.Remove(target);
                    continue;
                }

                if (last_same_name_node != null)
                {
                    last_same_name_node.InsertAfter(domNew.ImportNode(element, true), last_same_name_node);
                    continue;
                }

                // 找到一个合适的位置插入
                insertSequence(element, new_root);
            }

            // 3) 在 new 中把没有被覆盖的标记了的字段全部删除
            foreach (XmlNode node in reserve_nodes)
            {
                node.ParentNode.RemoveChild(node);
            }

            strNewBiblioXml = domNew.DocumentElement.OuterXml;
            return 0;
        }