Example #1
0
		// 处理一条记录对应于一个<record>定义
		// container参数完全可能为null,这表示<record>为根元素
		// return:
		//		-1	出错
		//		0	正常返回
		int DoSingleItem(
			object objParam,
			XmlNode node,
			int nIndex,
			FilterItem container,
			string strData,
			string strNextName,
			out BreakType breakType,
			out string strError)
		{
			strError = "";
			breakType = BreakType.None;

			/*
			Debug.Assert(node != null, "node参数不能为null");

			HashFilterItem itemNode = (HashFilterItem)NodeTable[node];

			if (itemNode == null) 
			{
				Debug.Assert(false, "NodeTable中缺乏事项");
				return -1;
			}

			Debug.Assert(node == itemNode.xmlNode, "item成员xmlNode不正确");

			Type entryClassType = itemNode.FunctionType;

			if (entryClassType == null) 
			{
				Debug.Assert(false, itemNode.FunctionName + "没有预先填充Type");
				return -1;
			}

			// 把fltx.cs代码中的Batch层对象new,并保持
			// new一个Batch派生对象
			FilterItem itemHost = (FilterItem)entryClassType.InvokeMember(null, 
				BindingFlags.DeclaredOnly | 
				BindingFlags.Public | BindingFlags.NonPublic | 
				BindingFlags.Instance | BindingFlags.CreateInstance, null, null,
				null);
			*/
			// 创建一个新FilterItem对象
			FilterItem itemHost = NewFilterItem(
				objParam,
				node,
				out strError);
			if (itemHost == null)
				return -1;

			itemHost.Data = strData;
			itemHost.Index = nIndex;
			itemHost.Container = container;
			// itemHost.FilterRoot = container != null ? container : itemHost;
			itemHost.FilterRoot = GetRootFilterItem(itemHost);

			Debug.Assert(itemHost.FilterRoot != null, "itemHost.FilterRoot不应当==null");

			if (node.Name == "record") 
			{
                itemHost.NodeType = NodeType.Record;
				itemHost.Data = strData;
				itemHost.Name = "";
				itemHost.Content = strData;
			}
			else if (node.Name == "field")
			{
                itemHost.NodeType = NodeType.Field;
                itemHost.Data = strData;
				if (strData.Length < 3) 
				{
					strError = "字段全部数据长度不足3字符";
					goto ERROR1;
				}
				itemHost.Name = strData.Substring(0, 3);	// 这里要求调用本函数的,准备头标区这个特殊“字段”时,要加上'hdr'2字符在内容前面
				// control field  001-009没有子字段
				if (FilterItem.IsControlFieldName(itemHost.Name) == true)
				{
					itemHost.Indicator = "";
					itemHost.Content = strData.Substring(3);
				}
				else 
				{
                    if (strData.Length >= 5)
                    {
                        itemHost.Indicator = strData.Substring(3, 2);
                        itemHost.Content = strData.Substring(5);
                    }
                    else
                    {
                        // 2006/11/24
                        itemHost.Indicator = "";
                        itemHost.Content = "";
                    }

				}
			}
			else if (node.Name == "group") 
			{
                itemHost.NodeType = NodeType.Group;
                itemHost.Data = strData;
				itemHost.Name = "";
				itemHost.Content = strData;
			}
			else if (node.Name == "subfield")
			{
                itemHost.NodeType = NodeType.Subfield;
                itemHost.Data = strData;
				if (strData.Length < 1) 
				{
					strError = "子字段全部数据长度不足1字符";
					goto ERROR1;
				}
				itemHost.Name = strData.Substring(0, 1);
				itemHost.Content = strData.Substring(1);
			}

			itemHost.SetDupCount();
			itemHost.NextName = strNextName;
			if (itemHost.Container != null) 
			{
				itemHost.PrevName = itemHost.Container.LastChildName;	// 利用上次遗留的

				// 这一句有点多余。因为本函数返回后, 后面立即会做修改LastChildName的事情
				itemHost.Container.LastChildName = itemHost.Name;	// 保存这次的
			}

			itemHost.OnBegin();

			// 检查无意义的break设置情况
			if (CheckBreakException == true
				&& node.Name == "subfield"
				&& (itemHost.Break == BreakType.SkipCaseEnd
				|| itemHost.Break == BreakType.SkipCase) )
			{
				throw(new Exception("<subfield>元素内script代码中用Break = ???改变结构匹配流程无任何意义..."));
			}


			if (itemHost.Break == BreakType.SkipCaseEnd)
				goto SKIP1;	// 不做OnEnd()
			if (itemHost.Break == BreakType.SkipCase)
				goto SKIP;	// 不做OnBegin的兄弟case,但是要做OnEnd()


			// int i;
			int nRet;
			// XmlNode child = null;
			BreakType thisBreak = BreakType.None;

			// <record>希望下级是<field>
			if (node.Name == "record") 
			{
				// 切割记录为若干字段,匹配case
				for(int r=0;;r++) 
				{
					string strField;
					string strNextFieldName;

					// 从记录中得到一个字段
					// parameters:
					//		strMARC		MARC记录
					//		strFieldName	字段名。如果==null,表示任意字段
					//		nIndex		同名字段中的第几个。从0开始计算(0表示头标区)
					//		strField	[out]输出字段。包括字段名、必要的字段指示符、字段内容。不包含字段结束符。
					//					注意头标区当作一个字段返回,strField中不包含字段名,一上来就是头标区内容
					// return:
					//		-1	error
					//		0	not found
					//		1	found
					nRet = MarcDocument.GetField(strData,
						null,
						r,
						out strField,
						out strNextFieldName);
					if (nRet == -1)
					{
                        // 2009/11/1
                        if (String.IsNullOrEmpty(strData) == true)
                            break;

                        strError = "DoSingleItem() GetField() error";
						return -1;
					}
					if (nRet == 0)
						break;

					if (strField.Length < 3)
						goto SKIP;


					string strFieldName = "";
					if (r != 0)
						strFieldName = strField.Substring(0,3);
					else 
					{
						strFieldName = "hdr";
						strField = strFieldName + strField;
					}
                    // ***
                    itemHost.IncChildDupCount(strFieldName);

					// for(i=0;i<node.ChildNodes.Count;i++) 
                    foreach(XmlNode child in node.ChildNodes)
					{
						// child = node.ChildNodes[i];

						if (child.NodeType != XmlNodeType.Element)
							continue;

						if (child.Name != "field")
							continue;

						// 匹配字段名
						nRet = MatchName( strFieldName, DomUtil.GetAttr(child, "name"));
						if (nRet == 1) 
						{
							nRet = DoSingleItem(
								objParam,
								child,
								r,
								itemHost,
								strField,
								strNextFieldName,
								out thisBreak,
								out strError);
							if (nRet == -1)
								return -1;

							if (itemHost.Break != BreakType.None)
								break;
						}


					} // end of for

					itemHost.LastChildName = strFieldName;	// 保存这次的
					if (itemHost.Break != BreakType.None)
						goto SKIP;

				}

			}
			else if (node.Name == "field")
			{

				// 若下级为subfield
				string strFirstChildName = GetFirstChildElementType(node);
				// field下的subfield
				if (strFirstChildName == "subfield") 
				{
					// 切割记录为若干子字段,匹配case
					for(int s=0;;s++) 
					{
						string strSubfield;
						string strNextSubfieldName;

						// 从字段或组中得到一个子字段
						// parameters:
						//		strText		字段内容,或者子字段组内容。
						//		textType	表示strText中包含的是字段内容还是组内容。
						//		strSubfieldName	子字段名。如果==null,表示任意子字段
						//					形式为'a'这样的。
						//		nIndex			同名子字段中的第几个。从0开始计算。
						//		strSubfield		输出子字段。子字段名(1字符)、子字段内容。
						//		strNextSubfieldName	下一个子字段的名字,一个字符
						// return:
						//		-1	error
						//		0	not found
						//		1	found
						nRet = MarcDocument.GetSubfield(strData,
							ItemType.Field,
							null,
							s,
							out strSubfield,
							out strNextSubfieldName);
						if (nRet == -1)
						{
							strError = "GetSubfield() error";
							return -1;
						}
						if (nRet == 0)
							break;

						if (strSubfield.Length < 1)
							goto SKIP;

						string strSubfieldName = strSubfield.Substring(0,1);

                        // ***
                        itemHost.IncChildDupCount(strSubfieldName);

						// for(i=0;i<node.ChildNodes.Count;i++) 
                        foreach(XmlNode child in node.ChildNodes)
						{
							// child = node.ChildNodes[i];

							if (child.NodeType != XmlNodeType.Element)
								continue;

							if (child.Name != "subfield")
								continue;

							// 匹配子字段名
							nRet = MatchName( strSubfieldName,  DomUtil.GetAttr(child, "name"));
							if (nRet == 1) 
							{
								nRet = DoSingleItem(
									objParam,
									child, 
									s,
									itemHost,
									strSubfield,
									strNextSubfieldName,
									out thisBreak,
									out strError);
								if (nRet == -1)
									return -1;
								if (itemHost.Break != BreakType.None)
									break;

							}

						} // end of for

						itemHost.LastChildName = strSubfieldName;	// 保存这次的
						if (itemHost.Break != BreakType.None)
							goto SKIP;

					}
				}
				// field下嵌套的field
				if (strFirstChildName == "field") 
				{
					// 切割字符串为若干字段,匹配case
					for(int r=0;;r++) 
					{
						string strField;
						string strNextFieldName;

						// 从记录中得到一个字段
						// parameters:
						//		strMARC		MARC记录
						//		strFieldName	字段名。如果==null,表示任意字段
						//		nIndex		同名字段中的第几个。从0开始计算(0表示头标区)
						//		strField	[out]输出字段。包括字段名、必要的字段指示符、字段内容。不包含字段结束符。
						//					注意头标区当作一个字段返回,strField中不包含字段名,一上来就是头标区内容
						// return:
						//		-1	error
						//		0	not found
						//		1	found
						nRet = MarcDocument.GetNestedField(strData,
							null,
							r,
							out strField,
							out strNextFieldName);
						if (nRet == -1)
						{
							strError = "GetNestedField() error";
							return -1;
						}
						if (nRet == 0)
							break;

						if (strField.Length < 3)
							goto SKIP;


						string strFieldName = "";
						strFieldName = strField.Substring(0,3);

                        // ***
                        itemHost.IncChildDupCount(strFieldName);

						// 嵌套字段不存在头标区'hdr'字段问题?

						//for(i=0;i<node.ChildNodes.Count;i++) 
                        foreach(XmlNode child in node.ChildNodes)
						{
							//child = node.ChildNodes[i];

							if (child.NodeType != XmlNodeType.Element)
								continue;

							if (child.Name != "field")
								continue;

							// 匹配字段名
							nRet = MatchName( strFieldName, DomUtil.GetAttr(child, "name"));
							if (nRet == 1) 
							{
								nRet = DoSingleItem(
									objParam,
									child,
									r,
									itemHost,
									strField,
									strNextFieldName,
									out thisBreak,
									out strError);
								if (nRet == -1)
									return -1;
								if (itemHost.Break != BreakType.None)
									break;
							}


						} // end of for

						itemHost.LastChildName = strFieldName;	// 保存这次的
						if (itemHost.Break != BreakType.None)
							goto SKIP;

					}

				}

				// field 下的group
				else if (strFirstChildName == "group") 
				{
					// 切割记录为若干子字段,匹配case
					for(int g=0;;g++) 
					{
						string strGroup;

						// 从字段中得到子字段组
						// parameters:
						//		strGroup	[out]结果。
						// return:
						//		-1	error
						//		0	not found
						//		1	found
						nRet = MarcDocument.GetGroup(strData,
							g,
							out strGroup);
						if (nRet == -1)
						{
							strError = "GetGroup() error";
							return -1;
						}
						if (nRet == 0)
							break;

						string strGroupName = Convert.ToString(g);

                        // ***
                        itemHost.IncChildDupCount(strGroupName);

						// for(i=0;i<node.ChildNodes.Count;i++) 
                        foreach(XmlNode child in node.ChildNodes)
						{
							// child = node.ChildNodes[i];

							if (child.NodeType != XmlNodeType.Element)
								continue;

							if (child.Name != "group")
								continue;

							// 匹配组名
							nRet = MatchName( strGroupName,  DomUtil.GetAttr(child, "name"));
							if (true/*nRet == 1*/) 
							{
								nRet = DoSingleItem(
									objParam,
									child,
									g,
									itemHost,
									strGroup, 
									"",
									out thisBreak,
									out strError);
								if (nRet == -1)
									return -1;
								if (itemHost.Break != BreakType.None)
									break;

							}

						} // end of for

						itemHost.LastChildName = "";	// 保存这次的
						if (itemHost.Break != BreakType.None)
							goto SKIP;

					}
				}

			}
			else if (node.Name == "group")
			{
				// 若下级为subfield
				string strFirstChildName = GetFirstChildElementType(node);
				if (strFirstChildName != "subfield") 
				{
					strError = ".fltx中<group>下级必须为<subfield>元素";
					return -1;
				}


				// 切割记录为若干子字段,匹配case
				for(int s=0;;s++) 
				{
					string strSubfield;
					string strNextSubfieldName;

					// 从字段或组中得到一个子字段
					// parameters:
					//		strText		字段内容,或者子字段组内容。
					//		textType	表示strText中包含的是字段内容还是组内容。
					//		strSubfieldName	子字段名。如果==null,表示任意子字段
					//					形式为'a'这样的。
					//		nIndex			同名子字段中的第几个。从0开始计算。
					//		strSubfield		输出子字段。子字段名(1字符)、子字段内容。
					//		strNextSubfieldName	下一个子字段的名字,一个字符
					// return:
					//		-1	error
					//		0	not found
					//		1	found
					nRet = MarcDocument.GetSubfield(strData,
						ItemType.Group,
						null,
						s,
						out strSubfield,
						out strNextSubfieldName);
					if (nRet == -1)
					{
						strError = "GetSubfield() error";
						return -1;
					}
					if (nRet == 0)
						break;

					if (strSubfield.Length < 1)
						goto SKIP;

					string strSubfieldName = strSubfield.Substring(0,1);
                    // ***
                    itemHost.IncChildDupCount(strSubfieldName);

					// for(i=0;i<node.ChildNodes.Count;i++) 
                    foreach (XmlNode child in node.ChildNodes)
                    {
						// child = node.ChildNodes[i];

						if (child.NodeType != XmlNodeType.Element)
							continue;

						if (child.Name != "subfield")
							continue;

						// 匹配子字段名
						nRet = MatchName( strSubfieldName,  DomUtil.GetAttr(child, "name"));
						if (nRet == 1) 
						{
							nRet = DoSingleItem(
								objParam,
								child,
								s,
								itemHost,
								strSubfield,
								strNextSubfieldName,
								out thisBreak,
								out strError);
							if (nRet == -1)
								return -1;
							if (itemHost.Break != BreakType.None)
								break;

						}

					} // end of for

					itemHost.LastChildName = strSubfieldName;	// 保存这次的
					if (itemHost.Break != BreakType.None)
						goto SKIP;


				}

			}			
			else if (node.Name == "subfield")
			{
				// 暂时没有什么处理

			}

			SKIP:

				if (itemHost.Break != BreakType.SkipCaseEnd) 
				{
					itemHost.OnEnd();
				}

           
			SKIP1:

				/*
				if (itemHost.Break != BreakType.None)
					return 1;
				*/

				breakType = itemHost.Break;

			return 0;

			ERROR1:
				return -1;
		}
Example #2
0
		FilterItem GetRootFilterItem(FilterItem start)
		{
			FilterItem item = start;
			for(;item!=null;) 
			{
				if (item.FilterRoot == item)
					return item;
				item = item.Container;
			}

			return null;
		}