import org.apache.axis.message.MessageElement;
import org.w3c.dom.*;
public List<TreeNodeBean> transformTree(String userType) throws Exception {
var result = service.wsGetTreeSubdir(strValidCode, 1, channelMap.get(userType), 0);
var anyArray = result.get_any();
if (anyArray == null || anyArray.length == 0) return List.of();
// 1) 找出 diffgram(略過 xs:schema)
Element diffgram = null;
for (MessageElement me : anyArray) {
String ln = me.getLocalName(); // localName 比 nodeName 安全(忽略前綴)
if ("diffgram".equalsIgnoreCase(ln)) {
diffgram = me;
break;
}
}
if (diffgram == null) {
// 有些服務把 diffgram 放在 schema 後面或包得更深,保險再掃一層
for (MessageElement me : anyArray) {
NodeList dgs = me.getElementsByTagNameNS("*", "diffgram");
if (dgs != null && dgs.getLength() > 0) {
diffgram = (Element) dgs.item(0);
break;
}
}
}
if (diffgram == null) {
LOGGER.warn("未找到 diffgr:diffgram 節點");
return List.of();
}
// 2) diffgram 內找到 <IQKB>(實際資料根)
Element dataRoot = firstChildElementByLocalName(diffgram, "IQKB");
if (dataRoot == null) {
// 保底:全域找也行
NodeList iqkbList = diffgram.getElementsByTagName("IQKB");
if (iqkbList != null && iqkbList.getLength() > 0) {
dataRoot = (Element) iqkbList.item(0);
}
}
if (dataRoot == null) {
LOGGER.warn("未找到 IQKB 節點(diffgram 有 schema 但無資料段)");
return List.of();
}
// 3) IQKB 內抓 <TreeSubdir>
NodeList list = dataRoot.getElementsByTagName("TreeSubdir");
if (list == null || list.getLength() == 0) {
LOGGER.warn("IQKB 內沒有 TreeSubdir");
return List.of();
}
// 4) 解析成 flat
List<TreeNodeBean> flatList = new ArrayList<>(list.getLength());
for (int i = 0; i < list.getLength(); i++) {
Element e = (Element) list.item(i);
String sftPath = getChildText(e, "sft_path"); // 用相容 Axis 的版本,別用 getTextContent
String iftSid = getChildText(e, "ift_sid");
String sftName = getChildText(e, "sft_name");
String iKBCount = getChildText(e, "iKBCount");
String dInit = getChildText(e, "dinit_time");
String dModi = getChildText(e, "dmodi_time");
String iftPrev = getChildText(e, "ift_prev");
TreeNodeBean child = new TreeNodeBean.Builder()
.ftSid(iftSid)
.ftName(sftName)
.parent(iftPrev)
.pathRaw(sftPath)
.pathParts(splitPathSafe(sftPath))
.kBCount(parseIntOrNull(iKBCount))
.initTime(parseDateTimeSafely(dInit, FORMATTER))
.modiTime(parseDateTimeSafely(dModi, FORMATTER))
.build();
flatList.add(child);
}
// 5) 建樹(只看 iftPrev)
List<TreeNodeBean> roots = TreeUtils.buildTree(flatList);
// 6) 你的既有慣例:回第一個 root 的 children
return roots.isEmpty() ? List.of() : roots.get(0).getChildren();
}
/* ---- 小幫手:找第一個子元素(用 localName 比對) ---- */
private static Element firstChildElementByLocalName(Element parent, String local) {
for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
String ln = n.getLocalName(); // 可能為 null(無 namespace)
String nn = n.getNodeName(); // 可能是 "IQKB" 或 "diffgr:diffgram"
if (local.equals(nn) || local.equalsIgnoreCase(ln)) {
return (Element) n;
}
}
}
return null;
}
/* ---- 取文本:Axis 相容版(保留你前面那套) ---- */
private static String getChildText(Element parent, String tag) {
NodeList nl = parent.getElementsByTagName(tag);
if (nl == null || nl.getLength() == 0) return "";
Node node = nl.item(0);
StringBuilder sb = new StringBuilder();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node c = children.item(i);
if (c.getNodeType() == Node.TEXT_NODE || c.getNodeType() == Node.CDATA_SECTION_NODE) {
sb.append(c.getNodeValue());
}
}
return sb.toString().trim();
}
aW1wb3J0IG9yZy5hcGFjaGUuYXhpcy5tZXNzYWdlLk1lc3NhZ2VFbGVtZW50OwoKaW1wb3J0IG9yZy53M2MuZG9tLio7CgoKCnB1YmxpYyBMaXN0PFRyZWVOb2RlQmVhbj4gdHJhbnNmb3JtVHJlZShTdHJpbmcgdXNlclR5cGUpIHRocm93cyBFeGNlcHRpb24gewoKICAgIHZhciByZXN1bHQgICA9IHNlcnZpY2Uud3NHZXRUcmVlU3ViZGlyKHN0clZhbGlkQ29kZSwgMSwgY2hhbm5lbE1hcC5nZXQodXNlclR5cGUpLCAwKTsKCiAgICB2YXIgYW55QXJyYXkgPSByZXN1bHQuZ2V0X2FueSgpOwoKICAgIGlmIChhbnlBcnJheSA9PSBudWxsIHx8IGFueUFycmF5Lmxlbmd0aCA9PSAwKSByZXR1cm4gTGlzdC5vZigpOwoKCgogICAgLy8gMSkg5om+5Ye6IGRpZmZncmFt77yI55Wl6YGOIHhzOnNjaGVtYe+8iQoKICAgIEVsZW1lbnQgZGlmZmdyYW0gPSBudWxsOwoKICAgIGZvciAoTWVzc2FnZUVsZW1lbnQgbWUgOiBhbnlBcnJheSkgewoKICAgICAgICBTdHJpbmcgbG4gPSBtZS5nZXRMb2NhbE5hbWUoKTsgICAgICAgICAvLyBsb2NhbE5hbWUg5q+UIG5vZGVOYW1lIOWuieWFqO+8iOW/veeVpeWJjee2tO+8iQoKICAgICAgICBpZiAoImRpZmZncmFtIi5lcXVhbHNJZ25vcmVDYXNlKGxuKSkgewoKICAgICAgICAgICAgZGlmZmdyYW0gPSBtZTsKCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICB9CgogICAgfQoKICAgIGlmIChkaWZmZ3JhbSA9PSBudWxsKSB7CgogICAgICAgIC8vIOacieS6m+acjeWLmeaKiiBkaWZmZ3JhbSDmlL7lnKggc2NoZW1hIOW+jOmdouaIluWMheW+l+abtOa3se+8jOS/nemaquWGjeaOg+S4gOWxpAoKICAgICAgICBmb3IgKE1lc3NhZ2VFbGVtZW50IG1lIDogYW55QXJyYXkpIHsKCiAgICAgICAgICAgIE5vZGVMaXN0IGRncyA9IG1lLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZGlmZmdyYW0iKTsKCiAgICAgICAgICAgIGlmIChkZ3MgIT0gbnVsbCAmJiBkZ3MuZ2V0TGVuZ3RoKCkgPiAwKSB7CgogICAgICAgICAgICAgICAgZGlmZmdyYW0gPSAoRWxlbWVudCkgZGdzLml0ZW0oMCk7CgogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICB9CgogICAgaWYgKGRpZmZncmFtID09IG51bGwpIHsKCiAgICAgICAgTE9HR0VSLndhcm4oIuacquaJvuWIsCBkaWZmZ3I6ZGlmZmdyYW0g56+A6bueIik7CgogICAgICAgIHJldHVybiBMaXN0Lm9mKCk7CgogICAgfQoKCgogICAgLy8gMikgZGlmZmdyYW0g5YWn5om+5YiwIDxJUUtCPu+8iOWvpumam+izh+aWmeague+8iQoKICAgIEVsZW1lbnQgZGF0YVJvb3QgPSBmaXJzdENoaWxkRWxlbWVudEJ5TG9jYWxOYW1lKGRpZmZncmFtLCAiSVFLQiIpOwoKICAgIGlmIChkYXRhUm9vdCA9PSBudWxsKSB7CgogICAgICAgIC8vIOS/neW6le+8muWFqOWfn+aJvuS5n+ihjAoKICAgICAgICBOb2RlTGlzdCBpcWtiTGlzdCA9IGRpZmZncmFtLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJJUUtCIik7CgogICAgICAgIGlmIChpcWtiTGlzdCAhPSBudWxsICYmIGlxa2JMaXN0LmdldExlbmd0aCgpID4gMCkgewoKICAgICAgICAgICAgZGF0YVJvb3QgPSAoRWxlbWVudCkgaXFrYkxpc3QuaXRlbSgwKTsKCiAgICAgICAgfQoKICAgIH0KCiAgICBpZiAoZGF0YVJvb3QgPT0gbnVsbCkgewoKICAgICAgICBMT0dHRVIud2Fybigi5pyq5om+5YiwIElRS0Ig56+A6bue77yIZGlmZmdyYW0g5pyJIHNjaGVtYSDkvYbnhKHos4fmlpnmrrXvvIkiKTsKCiAgICAgICAgcmV0dXJuIExpc3Qub2YoKTsKCiAgICB9CgoKCiAgICAvLyAzKSBJUUtCIOWFp+aKkyA8VHJlZVN1YmRpcj4KCiAgICBOb2RlTGlzdCBsaXN0ID0gZGF0YVJvb3QuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRyZWVTdWJkaXIiKTsKCiAgICBpZiAobGlzdCA9PSBudWxsIHx8IGxpc3QuZ2V0TGVuZ3RoKCkgPT0gMCkgewoKICAgICAgICBMT0dHRVIud2FybigiSVFLQiDlhafmspLmnIkgVHJlZVN1YmRpciIpOwoKICAgICAgICByZXR1cm4gTGlzdC5vZigpOwoKICAgIH0KCgoKICAgIC8vIDQpIOino+aekOaIkCBmbGF0CgogICAgTGlzdDxUcmVlTm9kZUJlYW4+IGZsYXRMaXN0ID0gbmV3IEFycmF5TGlzdDw+KGxpc3QuZ2V0TGVuZ3RoKCkpOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGlzdC5nZXRMZW5ndGgoKTsgaSsrKSB7CgogICAgICAgIEVsZW1lbnQgZSA9IChFbGVtZW50KSBsaXN0Lml0ZW0oaSk7CgoKCiAgICAgICAgU3RyaW5nIHNmdFBhdGggID0gZ2V0Q2hpbGRUZXh0KGUsICJzZnRfcGF0aCIpOyAgIC8vIOeUqOebuOWuuSBBeGlzIOeahOeJiOacrO+8jOWIpeeUqCBnZXRUZXh0Q29udGVudAoKICAgICAgICBTdHJpbmcgaWZ0U2lkICAgPSBnZXRDaGlsZFRleHQoZSwgImlmdF9zaWQiKTsKCiAgICAgICAgU3RyaW5nIHNmdE5hbWUgID0gZ2V0Q2hpbGRUZXh0KGUsICJzZnRfbmFtZSIpOwoKICAgICAgICBTdHJpbmcgaUtCQ291bnQgPSBnZXRDaGlsZFRleHQoZSwgImlLQkNvdW50Iik7CgogICAgICAgIFN0cmluZyBkSW5pdCAgICA9IGdldENoaWxkVGV4dChlLCAiZGluaXRfdGltZSIpOwoKICAgICAgICBTdHJpbmcgZE1vZGkgICAgPSBnZXRDaGlsZFRleHQoZSwgImRtb2RpX3RpbWUiKTsKCiAgICAgICAgU3RyaW5nIGlmdFByZXYgID0gZ2V0Q2hpbGRUZXh0KGUsICJpZnRfcHJldiIpOwoKCgogICAgICAgIFRyZWVOb2RlQmVhbiBjaGlsZCA9IG5ldyBUcmVlTm9kZUJlYW4uQnVpbGRlcigpCgogICAgICAgICAgICAgICAgLmZ0U2lkKGlmdFNpZCkKCiAgICAgICAgICAgICAgICAuZnROYW1lKHNmdE5hbWUpCgogICAgICAgICAgICAgICAgLnBhcmVudChpZnRQcmV2KQoKICAgICAgICAgICAgICAgIC5wYXRoUmF3KHNmdFBhdGgpCgogICAgICAgICAgICAgICAgLnBhdGhQYXJ0cyhzcGxpdFBhdGhTYWZlKHNmdFBhdGgpKQoKICAgICAgICAgICAgICAgIC5rQkNvdW50KHBhcnNlSW50T3JOdWxsKGlLQkNvdW50KSkKCiAgICAgICAgICAgICAgICAuaW5pdFRpbWUocGFyc2VEYXRlVGltZVNhZmVseShkSW5pdCwgRk9STUFUVEVSKSkKCiAgICAgICAgICAgICAgICAubW9kaVRpbWUocGFyc2VEYXRlVGltZVNhZmVseShkTW9kaSwgRk9STUFUVEVSKSkKCiAgICAgICAgICAgICAgICAuYnVpbGQoKTsKCgoKICAgICAgICBmbGF0TGlzdC5hZGQoY2hpbGQpOwoKICAgIH0KCgoKICAgIC8vIDUpIOW7uuaoue+8iOWPqueciyBpZnRQcmV277yJCgogICAgTGlzdDxUcmVlTm9kZUJlYW4+IHJvb3RzID0gVHJlZVV0aWxzLmJ1aWxkVHJlZShmbGF0TGlzdCk7CgoKCiAgICAvLyA2KSDkvaDnmoTml6LmnInmhaPkvovvvJrlm57nrKzkuIDlgIsgcm9vdCDnmoQgY2hpbGRyZW4KCiAgICByZXR1cm4gcm9vdHMuaXNFbXB0eSgpID8gTGlzdC5vZigpIDogcm9vdHMuZ2V0KDApLmdldENoaWxkcmVuKCk7Cgp9CgoKCi8qIC0tLS0g5bCP5bmr5omL77ya5om+56ys5LiA5YCL5a2Q5YWD57Sg77yI55SoIGxvY2FsTmFtZSDmr5TlsI3vvIkgLS0tLSAqLwoKcHJpdmF0ZSBzdGF0aWMgRWxlbWVudCBmaXJzdENoaWxkRWxlbWVudEJ5TG9jYWxOYW1lKEVsZW1lbnQgcGFyZW50LCBTdHJpbmcgbG9jYWwpIHsKCiAgICBmb3IgKE5vZGUgbiA9IHBhcmVudC5nZXRGaXJzdENoaWxkKCk7IG4gIT0gbnVsbDsgbiA9IG4uZ2V0TmV4dFNpYmxpbmcoKSkgewoKICAgICAgICBpZiAobi5nZXROb2RlVHlwZSgpID09IE5vZGUuRUxFTUVOVF9OT0RFKSB7CgogICAgICAgICAgICBTdHJpbmcgbG4gPSBuLmdldExvY2FsTmFtZSgpOyAgICAgICAgICAgICAgIC8vIOWPr+iDveeCuiBudWxs77yI54ShIG5hbWVzcGFjZe+8iQoKICAgICAgICAgICAgU3RyaW5nIG5uID0gbi5nZXROb2RlTmFtZSgpOyAgICAgICAgICAgICAgICAvLyDlj6/og73mmK8gIklRS0IiIOaIliAiZGlmZmdyOmRpZmZncmFtIgoKICAgICAgICAgICAgaWYgKGxvY2FsLmVxdWFscyhubikgfHwgbG9jYWwuZXF1YWxzSWdub3JlQ2FzZShsbikpIHsKCiAgICAgICAgICAgICAgICByZXR1cm4gKEVsZW1lbnQpIG47CgogICAgICAgICAgICB9CgogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIG51bGw7Cgp9CgoKCi8qIC0tLS0g5Y+W5paH5pys77yaQXhpcyDnm7jlrrnniYjvvIjkv53nlZnkvaDliY3pnaLpgqPlpZfvvIkgLS0tLSAqLwoKcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldENoaWxkVGV4dChFbGVtZW50IHBhcmVudCwgU3RyaW5nIHRhZykgewoKICAgIE5vZGVMaXN0IG5sID0gcGFyZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZyk7CgogICAgaWYgKG5sID09IG51bGwgfHwgbmwuZ2V0TGVuZ3RoKCkgPT0gMCkgcmV0dXJuICIiOwoKICAgIE5vZGUgbm9kZSA9IG5sLml0ZW0oMCk7CgogICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CgogICAgTm9kZUxpc3QgY2hpbGRyZW4gPSBub2RlLmdldENoaWxkTm9kZXMoKTsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGNoaWxkcmVuLmdldExlbmd0aCgpOyBpKyspIHsKCiAgICAgICAgTm9kZSBjID0gY2hpbGRyZW4uaXRlbShpKTsKCiAgICAgICAgaWYgKGMuZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLlRFWFRfTk9ERSB8fCBjLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKCiAgICAgICAgICAgIHNiLmFwcGVuZChjLmdldE5vZGVWYWx1ZSgpKTsKCiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gc2IudG9TdHJpbmcoKS50cmltKCk7Cgp9Cg==