|
@@ -2261,15 +2261,13 @@ public class WorkReimbursementService extends CrudService<WorkReimbursementDao,
|
|
|
*/
|
|
*/
|
|
|
public Map<String,String> xmlNodeListDataDispose(NodeList nodeList,Document document){
|
|
public Map<String,String> xmlNodeListDataDispose(NodeList nodeList,Document document){
|
|
|
Map<String,String> map = new HashMap<>();
|
|
Map<String,String> map = new HashMap<>();
|
|
|
|
|
+ Map<String, Integer> keyCounter = new HashMap<>(); // 同名节点计数器
|
|
|
if(null != nodeList && nodeList.getLength()>0){
|
|
if(null != nodeList && nodeList.getLength()>0){
|
|
|
- //遍历每一个header节点
|
|
|
|
|
for (int i = 0; i < nodeList.getLength(); i++) {
|
|
for (int i = 0; i < nodeList.getLength(); i++) {
|
|
|
- //通过 item(i)方法 获取一个header节点,nodelist的索引值从0开始
|
|
|
|
|
- Node header = nodeList.item(i);
|
|
|
|
|
- //解析定义节点的子节点
|
|
|
|
|
- NodeList childNodes = header.getChildNodes();
|
|
|
|
|
- //节点数据处理
|
|
|
|
|
- Map<String,String> map1 = xmlDataDispose(childNodes, document);
|
|
|
|
|
|
|
+ Node topNode = nodeList.item(i); // 0层:Header/EInvoiceData/TaxSupervisionInfo
|
|
|
|
|
+ NodeList childNodes = topNode.getChildNodes();
|
|
|
|
|
+ // 初始化层级为1(顶层直接子节点),父前缀为空
|
|
|
|
|
+ Map<String,String> map1 = xmlDataDispose(childNodes, document, "", 1, keyCounter);
|
|
|
map.putAll(map1);
|
|
map.putAll(map1);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -2277,42 +2275,47 @@ public class WorkReimbursementService extends CrudService<WorkReimbursementDao,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 子节点遍历获取参数,若其下还有子节点,则循环调用 xmlNodeListDataDispose 方法
|
|
|
|
|
- * @param childNodes
|
|
|
|
|
- * @param document
|
|
|
|
|
- * @return
|
|
|
|
|
|
|
+ * 修复同名节点重复拼接问题:第2层与第1层同名时,仅保留1次节点名
|
|
|
|
|
+ * 规则:0/1层不拼接,2层若与1层同名则不重复拼接,3层及以下正常拼接
|
|
|
*/
|
|
*/
|
|
|
- public Map<String,String> xmlDataDispose(NodeList childNodes,Document document){
|
|
|
|
|
|
|
+ public Map<String,String> xmlDataDispose(NodeList childNodes,Document document, String parentPrefix, int currentLevel, Map<String, Integer> keyCounter){
|
|
|
Map<String,String> map = new HashMap<>();
|
|
Map<String,String> map = new HashMap<>();
|
|
|
for (int k = 0; k < childNodes.getLength(); k++) {
|
|
for (int k = 0; k < childNodes.getLength(); k++) {
|
|
|
- // 区分出text类型的node以及element类型的node
|
|
|
|
|
if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
|
|
if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
|
|
|
- Node firstChild = childNodes.item(k).getFirstChild();
|
|
|
|
|
- if(null != firstChild){
|
|
|
|
|
- if(StringUtils.isBlank(childNodes.item(k).getFirstChild().getNodeValue())){
|
|
|
|
|
- // 获取所有header节点的集合
|
|
|
|
|
- NodeList childList = document.getElementsByTagName(childNodes.item(k).getNodeName());
|
|
|
|
|
-
|
|
|
|
|
- String parentName = childNodes.item(k).getNodeName();
|
|
|
|
|
- //循环调用,获取最低级节点数据信息
|
|
|
|
|
- Map<String,String> map1 = xmlNodeListDataDispose(childList, document);
|
|
|
|
|
- Map<String,String> map2 = new HashMap<>();
|
|
|
|
|
- if(map1.size()>0){
|
|
|
|
|
- //将获取到的数据进行遍历,添加父节点的参数信息,防止子节点key键相同,导致数据被覆盖
|
|
|
|
|
- for (String key : map1.keySet()) {
|
|
|
|
|
- if(key.contains("-")){
|
|
|
|
|
- String newKey = key.replaceAll("-","");
|
|
|
|
|
- map2.put(parentName + newKey,map1.get(key));
|
|
|
|
|
- }else{
|
|
|
|
|
- map2.put(parentName + key,map1.get(key));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- map.putAll(map2);
|
|
|
|
|
|
|
+ Node currentNode = childNodes.item(k);
|
|
|
|
|
+ String nodeName = currentNode.getNodeName();
|
|
|
|
|
+ // 【核心新增:去除节点名中的 `-` 字符】
|
|
|
|
|
+ String cleanNodeName = nodeName.replaceAll("-", ""); // 关键步骤:替换所有 `-` 为空
|
|
|
|
|
+ NodeList grandChildNodes = currentNode.getChildNodes();
|
|
|
|
|
+
|
|
|
|
|
+ // 拼接逻辑(改用处理后的 cleanNodeName)
|
|
|
|
|
+ String currentKeyPrefix;
|
|
|
|
|
+ if (currentLevel == 1) {
|
|
|
|
|
+ // 第1层:用处理后的节点名作为前缀
|
|
|
|
|
+ currentKeyPrefix = cleanNodeName;
|
|
|
|
|
+ } else if (currentLevel == 2) {
|
|
|
|
|
+ // 第2层:判断是否与第1层前缀同名(基于处理后的名称)
|
|
|
|
|
+ if (cleanNodeName.equals(parentPrefix)) {
|
|
|
|
|
+ currentKeyPrefix = parentPrefix;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ currentKeyPrefix = parentPrefix + cleanNodeName;
|
|
|
}
|
|
}
|
|
|
- //判定key 和value 值均存在,则进行储存,否则不进行储存
|
|
|
|
|
- if(StringUtils.isNotBlank(childNodes.item(k).getNodeName()) && StringUtils.isNotBlank(childNodes.item(k).getFirstChild().getNodeValue())){
|
|
|
|
|
- map.put(childNodes.item(k).getNodeName(),childNodes.item(k).getFirstChild().getNodeValue());
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 第3层及以上:正常拼接处理后的节点名
|
|
|
|
|
+ currentKeyPrefix = parentPrefix + cleanNodeName;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取节点文本值
|
|
|
|
|
+ String textValue = getNodeTextValue(grandChildNodes);
|
|
|
|
|
+ if (StringUtils.isNotBlank(textValue)) {
|
|
|
|
|
+ // 生成不重复的最终key(基于处理后的前缀)
|
|
|
|
|
+ String finalKey = generateUniqueKey(currentKeyPrefix, keyCounter);
|
|
|
|
|
+ map.put(finalKey, textValue);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 无文本值,递归时传递处理后的前缀
|
|
|
|
|
+ if (hasChildElements(grandChildNodes)) {
|
|
|
|
|
+ Map<String,String> childMap = xmlDataDispose(grandChildNodes, document, currentKeyPrefix, currentLevel + 1, keyCounter);
|
|
|
|
|
+ map.putAll(childMap);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -2321,6 +2324,45 @@ public class WorkReimbursementService extends CrudService<WorkReimbursementDao,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 提取节点有效文本值(仅保留非空白文本)
|
|
|
|
|
+ */
|
|
|
|
|
+ private String getNodeTextValue(NodeList childNodes) {
|
|
|
|
|
+ StringBuilder text = new StringBuilder();
|
|
|
|
|
+ for (int i = 0; i < childNodes.getLength(); i++) {
|
|
|
|
|
+ Node child = childNodes.item(i);
|
|
|
|
|
+ if (child.getNodeType() == Node.TEXT_NODE) {
|
|
|
|
|
+ String trimText = StringUtils.trim(child.getNodeValue());
|
|
|
|
|
+ if (StringUtils.isNotBlank(trimText)) {
|
|
|
|
|
+ text.append(trimText);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return text.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断是否有子元素节点
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean hasChildElements(NodeList childNodes) {
|
|
|
|
|
+ for (int i = 0; i < childNodes.getLength(); i++) {
|
|
|
|
|
+ if (childNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 生成不重复key(同名节点加序号,避免覆盖)
|
|
|
|
|
+ */
|
|
|
|
|
+ private String generateUniqueKey(String keyPrefix, Map<String, Integer> keyCounter) {
|
|
|
|
|
+ int count = keyCounter.getOrDefault(keyPrefix, 0) + 1;
|
|
|
|
|
+ keyCounter.put(keyPrefix, count);
|
|
|
|
|
+ return count == 1 ? keyPrefix : keyPrefix + count;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 根据id修改报销详情中喝项目的关联关系信息
|
|
* 根据id修改报销详情中喝项目的关联关系信息
|
|
|
* @param invoiceNumber
|
|
* @param invoiceNumber
|
|
|
* @return
|
|
* @return
|