/** * 获取 R8 xliff文件的所有批注信息 * * @param vn * @param tgtbeBean */ private void getNotes(VTDNav vn, TuMrkBean tgtbeBean) throws Exception { vn.push(); List<CommentBean> segCommentList = new LinkedList<CommentBean>(); AutoPilot ap = new AutoPilot(vn); String xpath = "./note"; ap.selectXPath(xpath); int atttIdx = -1; CommentBean bean; while (ap.evalXPath() != -1) { boolean isCurrent = true; if ((atttIdx = vn.getAttrVal("hs:apply-current")) != -1) { if ("no".equalsIgnoreCase(vn.toString(atttIdx))) { isCurrent = false; } } String user = ""; String date = ""; String commentText = ""; // R8 xliff 文件中没有提示级别一属性,故此处皆为供参考 String severity = "Low"; if ((atttIdx = vn.getAttrVal("from")) != -1) { user = vn.toString(atttIdx); } if (vn.getText() != -1) { String r8NoteText = vn.toString(vn.getText()); if (r8NoteText.indexOf(":") != -1) { date = r8NoteText.substring(0, r8NoteText.indexOf(":")); commentText = r8NoteText.substring(r8NoteText.indexOf(":") + 1, r8NoteText.length()); } else { commentText = r8NoteText; } } bean = new CommentBean(user, date, severity, commentText, true); if (isCurrent) { segCommentList.add(new CommentBean(user, date, severity, commentText, true)); } else { if (!fileCommentsList.contains(bean)) { fileCommentsList.add(bean); } } } tgtbeBean.setCommentList(segCommentList); vn.pop(); }
/** * 替换掉骨架文件中的占位符 * * @param segId * @param srcBean * @param tgtbeBean */ private void replaceSegment(String segId, TuMrkBean srcBean, TuMrkBean tgtbeBean) throws Exception { String segStr = "%%%" + segId + "%%%"; String srcXpath = "/xliff/file/body//trans-unit/seg-source//mrk[text()='" + segStr + "']"; // 先处理源文 outputAP.selectXPath(srcXpath); if (outputAP.evalXPath() != -1) { int textIdx = outputVN.getText(); outputXM.updateToken(textIdx, srcBean.getContent().getBytes("utf-8")); } // 处理译文 String tgtXpath = "/xliff/file/body//trans-unit/target//mrk[text()='" + segStr + "']"; outputAP.selectXPath(tgtXpath); if (outputAP.evalXPath() != -1) { String content = tgtbeBean.getContent(); if (tgtbeBean.getCommentList().size() > 0) { String uuId = CommonFunction.createUUID(); commentMap.put(uuId, tgtbeBean.getCommentList()); content = "<mrk mtype=\"x-sdl-comment\" sdl:cid=\"" + uuId + "\">" + tgtbeBean.getContent() + "</mrk>"; } int textIdx = outputVN.getText(); outputXM.updateToken(textIdx, content.getBytes("utf-8")); // 开始处理状态 int attrIdx = -1; if ((attrIdx = outputVN.getAttrVal("mid")) != -1) { boolean needLocked = false; String mid = outputVN.toString(attrIdx); // 下面根据mid找到对应的sdl:seg节点,这个节点里面存放的有每个文本段的状态 String xpath = "ancestor::trans-unit/sdl:seg-defs/sdl:seg[@id='" + mid + "']"; outputAP.selectXPath(xpath); if (outputAP.evalXPath() != -1) { // 先判断是否锁定 if (tgtbeBean.isLocked()) { if ((attrIdx = outputVN.getAttrVal("locked")) != -1) { if (!"true".equals(outputVN.toString(attrIdx))) { outputXM.updateToken(attrIdx, "true"); } } else { needLocked = true; } } else { if ((attrIdx = outputVN.getAttrVal("locked")) != -1) { if ("true".equals(outputVN.toString(attrIdx))) { outputXM.updateToken(attrIdx, "false"); } } } // 下面根据R8的状态。修改sdl的状态。 String conf = ""; String status = tgtbeBean.getStatus(); if ("new".equals(status)) { conf = "Draft"; } else if ("translated".equals(status)) { conf = "Translated"; } else if ("approved".equals(status)) { conf = "ApprovedTranslation"; } else if ("signed-off".equals(status)) { conf = "ApprovedSignOff"; } if ("".equals(conf)) { if ((attrIdx = outputVN.getAttrVal("conf")) != -1) { outputXM.updateToken(attrIdx, ""); } } else { if ((attrIdx = outputVN.getAttrVal("conf")) != -1) { if (!conf.equals(outputVN.toString(attrIdx))) { outputXM.updateToken(attrIdx, conf); } } else { String attributeStr = ""; if (needLocked) { attributeStr = " locked=\"true\" "; } attributeStr += " conf=\"" + conf + "\" "; outputXM.insertAttribute(attributeStr.getBytes("utf-8")); needLocked = false; } } if (needLocked) { outputXM.insertAttribute(" locked=\"true\" ".getBytes("utf-8")); } } } } }
/** * 分析xliff文件的每一个 trans-unit 节点 * * @throws Exception */ private void ananysisXlfTU(IProgressMonitor monitor) throws Exception { if (monitor == null) { monitor = new NullProgressMonitor(); } AutoPilot ap = new AutoPilot(xlfVN); AutoPilot childAP = new AutoPilot(xlfVN); VTDUtils vu = new VTDUtils(xlfVN); String xpath = "count(/xliff/file/body//trans-unit)"; ap.selectXPath(xpath); int totalTuNum = (int) ap.evalXPathToNumber(); if (totalTuNum > 500) { workInterval = totalTuNum / 500; } int matchWorkUnit = totalTuNum % workInterval == 0 ? (totalTuNum / workInterval) : (totalTuNum / workInterval) + 1; monitor.beginTask("", matchWorkUnit); xpath = "/xliff/file/body//trans-unit"; String srcXpath = "./source"; String tgtXpath = "./target"; ap.selectXPath(xpath); int attrIdx = -1; // trans-unit的id,对应sdl文件的占位符如%%%1%%% 。 String segId = ""; TuMrkBean srcBean = null; TuMrkBean tgtBean = null; int traversalTuIndex = 0; while (ap.evalXPath() != -1) { traversalTuIndex++; if ((attrIdx = xlfVN.getAttrVal("id")) == -1) { continue; } srcBean = new TuMrkBean(); tgtBean = new TuMrkBean(); segId = xlfVN.toString(attrIdx); // 处理source节点 xlfVN.push(); childAP.selectXPath(srcXpath); if (childAP.evalXPath() != -1) { String srcContent = vu.getElementContent(); srcContent = srcContent == null ? "" : srcContent; srcBean.setContent(srcContent); srcBean.setSource(true); } xlfVN.pop(); // 处理target节点 String status = ""; // 状态,针对target节点,空字符串为未翻译 xlfVN.push(); tgtBean.setSource(false); String tgtContent = null; childAP.selectXPath(tgtXpath); if (childAP.evalXPath() != -1) { tgtContent = vu.getElementContent(); if ((attrIdx = xlfVN.getAttrVal("state")) != -1) { status = xlfVN.toString(attrIdx); } } tgtContent = tgtContent == null ? "" : tgtContent; tgtBean.setContent(tgtContent); xlfVN.pop(); // 处理批注 getNotes(xlfVN, tgtBean); // 判断是否处于锁定状态 if ((attrIdx = xlfVN.getAttrVal("translate")) != -1) { if ("no".equalsIgnoreCase(xlfVN.toString(attrIdx))) { tgtBean.setLocked(true); } } // 判断是否处于批准状态,若是签发,就没有必要判断了,因为签发了的一定就批准了的 if (!"signed-off".equalsIgnoreCase(status)) { if ((attrIdx = xlfVN.getAttrVal("approved")) != -1) { if ("yes".equalsIgnoreCase(xlfVN.toString(attrIdx))) { status = "approved"; // 批准 } } } tgtBean.setStatus(status); replaceSegment(segId, srcBean, tgtBean); monitorWork(monitor, traversalTuIndex, false); } monitorWork(monitor, traversalTuIndex, true); }