Marc数据解析和拼接(java版)

mac2025-10-20  6

解析marc数据:

marc数据分为三部分:标识区、目次区、数据记录区。详情请仔细查找资料,本文不多介绍,直接上代码

import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JMarc { static Map<String, String> map=new HashMap<String, String>();//解析集合 public Map<String, String> jxMarc(String marc){ originalMap(); String m=marc.split("\\u001D")[0]; String s1=m.split("\\u001E")[0]; String s2=(String) s1.subSequence(5, 6); if(s2.equals("d")){ System.err.println("检测到数据已废除!错误发生在:标识区状态为‘d’"); return map; } int s3=Integer.parseInt(s1.substring(12,17)); String s4=s1.substring(24,s3-1); if(s4.length()%12!=0) { System.err.println("检测到数据格式错误!错误发生在:地址目次区"); return map; } List<String> list1=new ArrayList<String>();//目次区集合 for(int i=0;i<s4.length()/12;i++) { list1.add( s4.substring( 12*i, 12*(i+1) ) ); } int k=m.split("\\u001E").length-1;//第一个数组是标识+目次区 String[] sz=m.split("\\u001E"); List<String> list2=new ArrayList<String>();//记录区集合 for(int i =0;i<k;i++) { list2.add(sz[i+1]); } if(list1.size()!=list2.size()) { System.err.println("检测到目次区与记录区数量不匹配!错误发生在:目次区或数据区," + "目次区:"+list1.size()+"组,记录区:"+list2.size()+"条"); return map; } //匹配 for(int i=0;i<list1.size();i++) { matchingMap(list1.get(i).substring(0,3),list2.get(i)); } return map; } //初始化map public Map<String, String> originalMap() { map.put("isbn", null);//ISBN map.put("title", null);//标题 map.put("divisionname", null);//分册名 map.put("divisionnumber", null);//分册号 map.put("author", null);//作者 map.put("oneprice", null);//价格 map.put("size", null);//尺寸 map.put("page", null);//页数、x册 map.put("published", null);//出版地 map.put("clc", null);//中图分类号 map.put("press", null);//出版社 map.put("pubdate", null);//出版时间 map.put("language", null);//语言 map.put("type", null);//主题 map.put("Remarks", null);//内容、简介 return map; } //匹配并赋值map public void matchingMap(String key1,String key2) { switch (key1) { case "010": if( key2.split("\\u001Fa").length>1 ) {//isbn String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("isbn", f2); } if(key2.split("\\u001Fd").length>1) {//价格 String f1=key2.split("\\u001Fd")[1]; String f2=f1.split("\\u001F")[0]; map.put("oneprice", f2); } break; case "101": if(key2.split("\\u001Fa").length>1) {//语言 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("language", f2); } break; case "200": if(key2.split("\\u001Ff").length>1) {//作者 String f1=key2.split("\\u001Ff")[1]; String f2=f1.split("\\u001F")[0]; map.put("author", f2); } if(key2.split("\\u001Fa").length>1) {//题名 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("title", f2); } if(key2.split("\\u001Fh").length>1) {//分册号***可能不止一个'@h' String f1=key2.split("\\u001Fh")[1]; String f2=f1.split("\\u001F")[0]; map.put("divisionnumber", f2); } if(key2.split("\\u001Fi").length>1) {//分册名***可能不止一个'@i' String f1=key2.split("\\u001Fi")[1]; String f2=f1.split("\\u001F")[0]; map.put("divisionname", f2); } break; case "210": if(key2.split("\\u001Fa").length>1) {//出版地 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("published", f2); } if(key2.split("\\u001Fc").length>1) {//出版社 String f1=key2.split("\\u001Fc")[1]; String f2=f1.split("\\u001F")[0]; map.put("press", f2); } if(key2.split("\\u001Fd").length>1) {//出版时间 String f1=key2.split("\\u001Fd")[1]; String f2=f1.split("\\u001F")[0]; map.put("pubdate",f2); } break; case "215": if(key2.split("\\u001Fd").length>1) {//尺寸 String f1=key2.split("\\u001Fd")[1]; String f2=f1.split("\\u001F")[0]; map.put("size", f2); } if(key2.split("\\u001Fa").length>1) {//页数***可能是层数 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("page", f2); } break; case "330": if(key2.split("\\u001Fa").length>1) {//内容 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("Remarks", f2); } break; case "606": if(key2.split("\\u001Fa").length>1) {//主题 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("type", f2); } break; case "690": if(key2.split("\\u001Fa").length>1) {//分类号 String f1=key2.split("\\u001Fa")[1]; String f2=f1.split("\\u001F")[0]; map.put("clc", f2); } break; default: break; } } }

将结果放到了map数组里。解析的数据都是规定好的,因为这是本人项目的一小部分,需要其他部分解析的可以参考资料添加解析。匹配类是单独的

拼接marc数据

会解析自然会拼接拉。直接上代码了。自己看吧:

public class PMarc { String marc1 = null;//第一段标识 String marc2 = null;//第二段目次 String marc3 = null;//第三段记录 String marc =null;//marc数据 char _RecordSplitChar = '\u001D'; // 区间分隔符 char _FieldSplitChar = '\u001E'; // 字段分割符 char _SubFieldSplitChar = '\u001F'; // 子字段分隔符 public String pjMarc( String isbn,String oneprice,String title,String author,String press,String clc) { //记录区 String s1=" "+_SubFieldSplitChar+"a"+isbn+_SubFieldSplitChar+"d"+oneprice; //010 isbn+价格 String s2=_FieldSplitChar+"1 "+_SubFieldSplitChar+"a"+title+_SubFieldSplitChar+"f"+author; //200 题名+作者 String s3=_FieldSplitChar+" "+_SubFieldSplitChar+"c"+press; //210 出版社 String s4=_FieldSplitChar+" "+_SubFieldSplitChar+"a"+clc ; //690 中图分类号 marc3=s1+s2+s3+s4; marc2="010"+String.format("%04d", s1.length())+String.format("%05d", 0) +"200"+String.format("%04d", s2.length())+String.format("%05d", 0+s1.length()) +"210"+String.format("%04d", s3.length())+String.format("%05d", 0+s1.length()+s2.length()) +"690"+String.format("%04d", s4.length())+String.format("%05d", 0+s1.length()+s2.length()+s3.length()) ; marc1=String.format("%05d", marc3.length()+marc2.length()+1) +"pam0"+" 22"+String.format("%05d",marc2.length()+1+24)+" "+"450 " ; marc=marc1+marc2+_FieldSplitChar+marc3+_RecordSplitChar; return marc; } }

拼接类拼接的比较简单,可以自行添加复杂,注意的是分隔符,很容易出错。

测试类

import java.util.HashMap; import java.util.Map; public class test { public static void main(String[] args) { Map<String, String> map=new HashMap<String, String>(); JMarc j=new JMarc(); PMarc p=new PMarc(); //拼接 String s=p.pjMarc("978-7-5463-4025-4", "CNY79.50", "诛仙", "萧鼎著", "起点小说网", "D67.475"); map=j.jxMarc(s);//解析测试 System.err.println(s); System.out.println(map); //解析 String s2="01141nam0 2200289 450 00100100000000500170001001000390002703500260006603500240009204900490011610000410016510100080020610200150021410500180022910600060024720001570025321000350041021500190044533001600046460700250062469000140064970100490066370200310071271200630074380100220080680100230082800011310320020928000000.0 a7-101-00183-1dCNY332.00(全二十册) a(A100000NLC)000113139 a(011001)c2001044106 aA100000NLCbUCS01000113103c000113139dNLC01 a20010709e19951956em y0chiy0110 ea0 achi aCNb110000 ay z 000yy ar1 a资治通鉴9zi zhi tong jianh第一册i卷一至一十二 周威烈王二十三年戊寅起 汉惠帝七年癸丑止b专著f(宋)司马光编著g(元)胡三省音注g“标点资治通鉴小组”校点 a北京c中华书局d1956h1995重印 a75,418页d20cm a《资治通鉴》为北宋司马光所编撰的编年体通史,共294卷。全书记载了上起周威王二十三年(公元前403年),下至五代周世宗显德六年(公元959年)的一千三百六十二年的历史。 a中国x古代史j编年体 aK204.3v4 0c(宋)a司马光f(1019-1086)9si ma guang4编著 0a胡三省9hu san sheng4音注02a标点资治通鉴小组9biao dian zi zhi tong jian xiao zu4校点 0aCNbNLCc20010717 2aCNbOLCCc20100923"; map=j.jxMarc(s2); System.out.println(map); } }

s2字符串中的marc数据乱码了。编码格式不同,建议自己去找一条marc数据去测试,可以去:中国国家图书馆找。 还有关于用z39.50协议套取mar数据的java方法可以去看我的另一篇yaz4j获取marc数据 套取marc方法类下载 -------------------------------------------------2019-11-01记载日志

最新回复(0)