Răsfoiți Sursa

fix: 改进 Run 文本提取,使用 XmlCursor 正确获取换行符

使用 Apache XMLBeans 的 XmlCursor 遍历 CTR 子元素,
按顺序处理 t(文本)、br(换行)、tab(制表符)、cr(回车) 等元素
何文松 4 săptămâni în urmă
părinte
comite
5c1a010ada

+ 34 - 14
backend/parse-service/src/main/java/com/lingyue/parse/service/WordStructuredExtractionService.java

@@ -600,21 +600,41 @@ public class WordStructuredExtractionService {
                 return xwpfRun.text();
             }
             
-            // 遍历 Run 内的所有元素
-            for (Object obj : ctr.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' ./*")) {
-                if (obj instanceof org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText) {
-                    // 普通文本
-                    org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText ctText = 
-                        (org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText) obj;
-                    sb.append(ctText.getStringValue());
-                } else if (obj instanceof org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr) {
-                    // 换行符 <w:br>
-                    sb.append("\n");
-                } else if (obj instanceof org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty) {
-                    // Tab 或其他空元素,检查元素名称
-                    // 暂时忽略
-                }
+            // 使用 POI 提供的直接方法获取文本和换行
+            // CTR 包含 t (text), br (break), tab 等元素
+            
+            // 获取所有文本元素
+            var tList = ctr.getTList();
+            var brList = ctr.getBrList();
+            var tabList = ctr.getTabList();
+            
+            // 如果没有换行和 tab,直接返回文本
+            if ((brList == null || brList.isEmpty()) && (tabList == null || tabList.isEmpty())) {
+                return xwpfRun.text();
             }
+            
+            // 需要按顺序处理,使用 XML 的 cursor
+            org.apache.xmlbeans.XmlCursor cursor = ctr.newCursor();
+            if (cursor.toFirstChild()) {
+                do {
+                    String localName = cursor.getName() != null ? cursor.getName().getLocalPart() : "";
+                    if ("t".equals(localName)) {
+                        // 文本
+                        sb.append(cursor.getTextValue());
+                    } else if ("br".equals(localName)) {
+                        // 换行
+                        sb.append("\n");
+                    } else if ("tab".equals(localName)) {
+                        // Tab
+                        sb.append("\t");
+                    } else if ("cr".equals(localName)) {
+                        // 回车
+                        sb.append("\n");
+                    }
+                } while (cursor.toNextSibling());
+            }
+            cursor.dispose();
+            
         } catch (Exception e) {
             // 如果 XML 解析失败,回退到简单方法
             log.debug("提取 Run 文本时出错,使用简单方法: {}", e.getMessage());

BIN
test/.~test.docx


BIN
test/test.docx