本記事は、一部AIが執筆しました。

概要

DHConvalidatorは、デジタル人文学(DH)会議の抄録を一貫したTEI(Text Encoding Initiative)テキストベースに変換するためのツールです。

https://github.com/ADHO/dhconvalidator

このツールの利用において、Microsoft Word形式(DOCX)からTEI XML形式への変換処理中に以下のようなエラーが発生するケースがありました:

ERROR:nu.xom.ParsingException:cvc-complex-type.2.4.a:Invalidcontentwasfoundstartingwithelement'ref'

この原因と対処方法について共有します。

原因の特定

調査の結果、問題の原因はWord文書内に埋め込まれた INCLUDEPICTUREフィールドコード であることが判明しました。

具体的には、Googleドキュメントから画像をコピー&ペーストした際に、以下のようなフィールドコードが文書内に残存していました:

INCLUDEPICTURE"https://lh7-rt.googleusercontent.com/docsz/..."MERGEFORMATINET

これらの外部画像参照リンクがTEI変換プロセスで適切に処理されず、XML検証エラーを引き起こしていました。

解決方法

この問題を解決するため、DOCXファイル内の問題のあるフィールドコードを自動的に除去するPythonスクリプトを開発しました。

スクリプトの特徴

  1. 安全な処理 : 画像コンテンツ自体は保持し、フィールドコード部分のみを削除
  2. ZIP形式対応 : DOCXファイルの内部構造(ZIP + XML)を適切に処理
  3. 名前空間対応 : Word文書のXML名前空間を考慮した正確な要素検索

主要な処理ロジック

  • DOCXファイルを一時ディレクトリに展開
  • word/document.xml内のフィールドコード構造を解析
  • INCLUDEPICTUREを含むフィールドを特定
  • フィールド制御要素(begin/separate/end)のみを削除し、画像要素は保持
  • 修正されたXMLで新しいDOCXファイルを生成

実装のポイント

フィールドコード判定

defifrsoe_rtiunriircunfnlnsutiFdirniaen_sflpttsifer'ecix_IrtettNeuleCtrd=xLue_tUr_rrDnfuuiEinnsPTes.Irl:fnCudioTe(ntUfdRi(NEe'o'l.nd/ei_/nrwau:ninidnsns,sittnrnrs_sTtt)ere:x_xttt'e.,xtten.xstt)e:xt:

削除対象の選別

defs#h#h#rhaaeosstu__ulfirdimn_earlghedeam__socc_voofenni_tterreluondnlt_(cr==ounn(r(rt,rururununonn.n.ls.f.f)fifia:ininnndnddd(d(('('n'.'.o..twwhw:w:a:i:psfndi_lsrcidtatmCrw'ahTi,gaenerxgn_'t'sc,',)o,nnnitsnsse)s)n)ntiiosistsnnNonoototnteNN)oNononeneeo)orr

結果

このスクリプトにより、問題のあるフィールドコードが除去され、TEI変換プロセスが正常に完了するようになりました。画像は適切に文書内に埋め込まれた状態で保持されます。

使用方法

pythonfix_docx_fields.pyinput.docx[output.docx]

出力ファイル名を指定しない場合、input_fixed.docxとして保存されます。

ただし、ファイルを開く際に以下の警告が表示されました。スクリプト側の修正方法がわからなかったのですが、「はい」ボタンを押すことで無事に開くことができました。

まとめ

GoogleドキュメントやWebブラウザから画像をコピーする際は、このような外部参照リンクが埋め込まれる可能性があります。

この問題は他のDOCX処理システムでも発生する可能性があるため、類似のエラーに遭遇した際の参考になれば幸いです。

スクリプト

#"DRt"iiiidddddi!"Oeh"mmmmeeeeef/"Cma"ppppfffffuXotoooosvrrrrp"PA"i#wpp"P"#tr#n}#r#f#tpi"C"frs"D"#h#h#rm"iiioite_mrFecttttr"rr"firr"r"roseorrs"h"oeh"e"aaea"mfnufrxna/isao"og"Ctio"o"PeoDFmPrSei_"e"rto"t"CsCsRti"pptycaibeuzxtoccsorhnccaete=ioraenicuueh_h_eunMolupn:emnilpsimesee:iouoe#w#di#wteerf'nvopr#r#iw#fv.tnkriirlrefeimr(arepstuopsppppse(ndreplmssnutuatiofi(sss==i{wdecauuhoew(cunfndmcicmon)itnry_ttryrrtry_)/of.pssptptteEtPcCtfssen'dernFnL=iRrrflins_ikekav:n(isf_isoiis_eCbTief_upupemxhr_orh"_Ete:a_sasisoleti"uftiFrnlgehssn.ifon.cnEn.nolEltidDtutuptzoxspefFdtXTrncs_no0er#fiemrphtRdirniaeeidieafyytelisteetxte=vdeIerloO_t_ttfrzicm.razoiohM.en'doitd=kulflouaeeeetn_sflmf_f_rsuss(xel.(xs(c(x=emeecCf_f_eiaipelpotirxceLpeahuenoinCdsvnr(mphttsoiccu_n."iepfis"efipacexXififmlcp_s_acepeua.mtrna_apfh_feeamxoiefer'evfroronfcaUt=a"t_Pp"t"yPto._lilipetfrsptefrfdmdrgetetcrrlao<=ecl#fj#w#i#i:ii.omvcix_Ireununsitrs(=tE(drtE(_trinEffelelo.ieahsniooeosespmhoelrrchdihftnrdletfettNe_antnteiga1shr1ooir1_hocvliieerTDlfdt.selorDncetp:o=omalrka_Fe=CiCS=+hei_duileCtrrewlovg)ys.r)ccor)moceeel(iaeOe.ohe_wetOtu(ra/vptor.Ieurcololhik=ermffred=xLuurhohnidn)esyeoxenoanefrmles(s=rmC.ecxd.,ffazC_mxoc/e0a.vufNnnfhudilenfnijes#frijuoii{el_tUrnualatt_:.sxr_sri3sisedtsypXZxu=ioDZiiriXxemoesrfeniC(so=an_leiefc_oep1pnvelr_drrDn(nsshcf<a.i:fsanseinstrtNioitmscOidllcpmnltscfaisnLr[rrdr+ejxex+kiRrm+rsedeefuuiEr==ooprasiisp_olot(o)rondrfpreotuCpiee__slt_(hign=dUuiructltn=neoto_(_mirnnsPTusfafnr2ygrtIenr_rdnTi:)npiaiFanssmXFr_poa(.f)eerdiaDn]fuifn1t<_d_ebicmfivo1btrXpoeus.Irnhi(rc(rrit:tvgsnlgeo"rnr:eurrlict.(eisipauvxximlaa[nlEsinsisr_fxr1floifelouMavln:fnCu,oerutruuerch[v(pd:c:ciepeP:teyelt.pdnfl,nattemmladpl]lP)e.ealurlteuvedae_nLtedsioTeulunuunnlooo1[iusceoseumaP_cDeaxaotieth.dlleshlt(I:lfnl=lenud_atdels_fmr)hd(ntUnldn.an..dlmn]2nt(osdstotafti(lmtc_l(ffhw__.c(h'Cdiodlnn_fkhedhrctae,_fcdRsd.fl.ffm]pimseua_vhtiorillh_xeoii=raffpoo'i.Tnt[(=sclipo_ouoetmcio(NE)cfifiicaafufnpisesfehlren(.xmull=isiiapd.s/Ubdbrrr.hdsinrunurioeoen'o':boiniinnonniitiplnsiteycptjmlteeot:lltee//Re(Neuuuraa_clulsncvnult.nenndmnddnddxf_lueg(.Elpot.tueol(pssoseeehns/pwEg'ognnnuprcitynd_ttecnda/eitd(ad((t_fettlTerorotmi_du:s.({_)xwa:i.ni]ssnphsu_thr:ot_i/nrr('g(''rnldli_efi,oier_pnpoti.pfoptm:rrfn/en)se=arfiro+eud}rnwaeo'.e'..ooioel'fdikbnopyf_(ac_npaiuaolpa'i/,u:[nraeine_=niu:niml..ltncne{ileolpul(idtt_fatlttf'g,ewanjdnn_emrfsnInIidnoc/ex()ilseueuta)liehxiothephro,rl:nlt](eiflfoe1igNsNnsvewwweh_s:neu:Itmtpcerm)mlsh._u)erandfdoinxsIidivme=C,Csitelw:nw::laufyp,cNpauea,)p:le..rpt:mmnpsloletNeeeol'LLtnrde:it:poessisuc{CutDt(s__,wjea_oash)pdfkx_nClcl_vduUnUrs_mfnedibm_ae.toeeLtiO''dpaoltfvt)aClftroLdodretDsDTtt(elsnrcjeigla_us}U_cCD.tria'liphies:thdfi_utU(n_u.fE)Eerecndttatenmedrfts"DfXOde'rtwkna,l.ta_oernDftrna-P:Px_xotCrw'cta.sgipf)EifCom),h'((teIoercrlu.NEiru(p8IItttnshT(i,tsg".vluuPlifXcp),trha}Nrr'hdnfoPeonfp'CC'e.taedn'e"p)etlIeeix_a'eo(r"Cgn,at)inIllsie,TT,xta(rxrgn,b_"y}_lC=llf'dswzmofc)L/srheneCd:enUUteib'ta'suc>'fyTNdei,ioipti_Uwn.endT_rldxRRn.xne,'w,)nto<i!Uolrzrp_,lpDosgd(aUrud(mEEsttsg,isni2nl"Rnce:idfdeaEr)ec'nRun_fl.)e:innni)ntnoe)Eeo_p'iif_tPdto.dEnsri_fxfnsngssoepet)))df_,lriphIp(m/s,uediti,)s)inul:eoire)la)Crfp/nf,nlee:e)ensittsffspxe'.:etTo'lweik,dcllsiliom.eor.tefdZ)hUc{e:xene_lddesiestnaduoid:oI,Re{tftlsenrapsmogoNnmo.cPEs{el_d)psurccanenNtecodndu_tsndf:)naooronnooxn"WaomDefisfCli:)tddatottnNc>e)olceEmin[ihdmieettseoor)xnFpeg"ea_aosseN)Nnn[d'tL_lmwlrcgn,oNooeto).Addl"d'he=wbnonr)eudxTi/],aThueenentomErc2}srcritnetpclD)o0}tn.ouldo)ouu')d0}rsgneen,rrtm)e6fu)et)o.eas/lcteptidnsmdt(nrnotwaCufteiscszhihr'smtxiinae{ear]pl'r{rgT"_eT{vee)oynixuppsncttre[go):e'"ns)wite"mer=]anv=}gti}e)n'}s.gbf"el)igdmiCanhg'ae:rsT.ype')=='end':