import org.apache.axis.message.MessageElement;
import org.w3c.dom.*;
import java.util.LinkedHashMap;
public LinkedHashMap<String, String> getTitleData(int iftSid, String userType) throws Exception {
LinkedHashMap<String, String> map = new LinkedHashMap<>();
IQKB_XMLSoapProxy service = new IQKB_XMLSoapProxy();
WsGetTreeAllKBResponseWsGetTreeAllKBResult result =
service.wsGetTreeAllKB(strValidCode, 1, channelMap.get(userType), iftSid, 1);
MessageElement[] anyArr = result.get_any();
if (anyArr == null || anyArr.length == 0) {
LOGGER.warn("getTitleData: get_any() 為空");
return map;
}
// 1) 找 diffgram(另一個通常是 xs:schema)
Element diffgram = null;
for (MessageElement me : anyArr) {
String ln = me.getLocalName();
if ("diffgram".equalsIgnoreCase(ln)) { diffgram = me; break; }
}
if (diffgram == null) {
LOGGER.warn("getTitleData: 找不到 diffgr:diffgram");
return map;
}
// 2) 進到資料根 IQKB(有些回應可能沒有這層,就用 diffgram)
Element dataRoot = firstChildElementByLocalName(diffgram, "IQKB");
if (dataRoot == null) dataRoot = diffgram;
// 3) 每一筆 row 是 <TreeAllKB>
NodeList rows = dataRoot.getElementsByTagName("TreeAllKB");
if (rows == null || rows.getLength() == 0) {
LOGGER.warn("getTitleData: IQKB 內沒有 TreeAllKB");
return map;
}
for (int i = 0; i < rows.getLength(); i++) {
Element row = (Element) rows.item(i);
// 在同一個 row 內取欄位,避免跨行錯配
String sid = getChildText(row, "ifq_sid");
String name = getChildText(row, "sfq_name");
if (!sid.isBlank()) {
map.put(sid.trim(), name == null ? "" : name.trim());
}
}
LOGGER.info("getTitleData: rows={}, mapped={}", rows.getLength(), map.size());
return map;
}
/* ===================== 共用 Private Helpers ===================== */
/** 找第一個子元素(用 localName 或 nodeName,比對字面 "IQKB" 等) */
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(); // 可能是 "diffgr:diffgram"
if (local.equals(nn) || local.equalsIgnoreCase(ln)) {
return (Element) n;
}
}
}
return null;
}
/** 取某個 tag 的文字值(Axis 相容;避免用 getTextContent()/toString()) */
private static String getChildText(Element parent, String tag) {
NodeList nl = parent.getElementsByTagName(tag);
if (nl == null || nl.getLength() == 0) return "";
return getNodeTextCompat(nl.item(0)).trim();
}
/** 相容 Axis MessageElement 的取文字:拼 TEXT_NODE / CDATA */
private static String getNodeTextCompat(Node node) {
if (node == null) return "";
StringBuilder sb = new StringBuilder();
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node c = children.item(i);
short t = c.getNodeType();
if (t == Node.TEXT_NODE || t == Node.CDATA_SECTION_NODE) {
sb.append(c.getNodeValue());
}
}
return sb.toString();
}
aW1wb3J0IG9yZy5hcGFjaGUuYXhpcy5tZXNzYWdlLk1lc3NhZ2VFbGVtZW50OwoKaW1wb3J0IG9yZy53M2MuZG9tLio7CgoKCmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKCgoKcHVibGljIExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGdldFRpdGxlRGF0YShpbnQgaWZ0U2lkLCBTdHJpbmcgdXNlclR5cGUpIHRocm93cyBFeGNlcHRpb24gewoKICAgIExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IG1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCgoKICAgIElRS0JfWE1MU29hcFByb3h5IHNlcnZpY2UgPSBuZXcgSVFLQl9YTUxTb2FwUHJveHkoKTsKCiAgICBXc0dldFRyZWVBbGxLQlJlc3BvbnNlV3NHZXRUcmVlQWxsS0JSZXN1bHQgcmVzdWx0ID0KCiAgICAgICAgICAgIHNlcnZpY2Uud3NHZXRUcmVlQWxsS0Ioc3RyVmFsaWRDb2RlLCAxLCBjaGFubmVsTWFwLmdldCh1c2VyVHlwZSksIGlmdFNpZCwgMSk7CgoKCiAgICBNZXNzYWdlRWxlbWVudFtdIGFueUFyciA9IHJlc3VsdC5nZXRfYW55KCk7CgogICAgaWYgKGFueUFyciA9PSBudWxsIHx8IGFueUFyci5sZW5ndGggPT0gMCkgewoKICAgICAgICBMT0dHRVIud2FybigiZ2V0VGl0bGVEYXRhOiBnZXRfYW55KCkg54K656m6Iik7CgogICAgICAgIHJldHVybiBtYXA7CgogICAgfQoKCgogICAgLy8gMSkg5om+IGRpZmZncmFt77yI5Y+m5LiA5YCL6YCa5bi45pivIHhzOnNjaGVtYe+8iQoKICAgIEVsZW1lbnQgZGlmZmdyYW0gPSBudWxsOwoKICAgIGZvciAoTWVzc2FnZUVsZW1lbnQgbWUgOiBhbnlBcnIpIHsKCiAgICAgICAgU3RyaW5nIGxuID0gbWUuZ2V0TG9jYWxOYW1lKCk7CgogICAgICAgIGlmICgiZGlmZmdyYW0iLmVxdWFsc0lnbm9yZUNhc2UobG4pKSB7IGRpZmZncmFtID0gbWU7IGJyZWFrOyB9CgogICAgfQoKICAgIGlmIChkaWZmZ3JhbSA9PSBudWxsKSB7CgogICAgICAgIExPR0dFUi53YXJuKCJnZXRUaXRsZURhdGE6IOaJvuS4jeWIsCBkaWZmZ3I6ZGlmZmdyYW0iKTsKCiAgICAgICAgcmV0dXJuIG1hcDsKCiAgICB9CgoKCiAgICAvLyAyKSDpgLLliLDos4fmlpnmoLkgSVFLQu+8iOacieS6m+WbnuaHieWPr+iDveaykuaciemAmeWxpO+8jOWwseeUqCBkaWZmZ3Jhbe+8iQoKICAgIEVsZW1lbnQgZGF0YVJvb3QgPSBmaXJzdENoaWxkRWxlbWVudEJ5TG9jYWxOYW1lKGRpZmZncmFtLCAiSVFLQiIpOwoKICAgIGlmIChkYXRhUm9vdCA9PSBudWxsKSBkYXRhUm9vdCA9IGRpZmZncmFtOwoKCgogICAgLy8gMykg5q+P5LiA562GIHJvdyDmmK8gPFRyZWVBbGxLQj4KCiAgICBOb2RlTGlzdCByb3dzID0gZGF0YVJvb3QuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIlRyZWVBbGxLQiIpOwoKICAgIGlmIChyb3dzID09IG51bGwgfHwgcm93cy5nZXRMZW5ndGgoKSA9PSAwKSB7CgogICAgICAgIExPR0dFUi53YXJuKCJnZXRUaXRsZURhdGE6IElRS0Ig5YWn5rKS5pyJIFRyZWVBbGxLQiIpOwoKICAgICAgICByZXR1cm4gbWFwOwoKICAgIH0KCgoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcm93cy5nZXRMZW5ndGgoKTsgaSsrKSB7CgogICAgICAgIEVsZW1lbnQgcm93ID0gKEVsZW1lbnQpIHJvd3MuaXRlbShpKTsKCgoKICAgICAgICAvLyDlnKjlkIzkuIDlgIsgcm93IOWFp+WPluashOS9je+8jOmBv+WFjei3qOihjOmMr+mFjQoKICAgICAgICBTdHJpbmcgc2lkICA9IGdldENoaWxkVGV4dChyb3csICJpZnFfc2lkIik7CgogICAgICAgIFN0cmluZyBuYW1lID0gZ2V0Q2hpbGRUZXh0KHJvdywgInNmcV9uYW1lIik7CgoKCiAgICAgICAgaWYgKCFzaWQuaXNCbGFuaygpKSB7CgogICAgICAgICAgICBtYXAucHV0KHNpZC50cmltKCksIG5hbWUgPT0gbnVsbCA/ICIiIDogbmFtZS50cmltKCkpOwoKICAgICAgICB9CgogICAgfQoKCgogICAgTE9HR0VSLmluZm8oImdldFRpdGxlRGF0YTogcm93cz17fSwgbWFwcGVkPXt9Iiwgcm93cy5nZXRMZW5ndGgoKSwgbWFwLnNpemUoKSk7CgogICAgcmV0dXJuIG1hcDsKCn0KCgoKLyogPT09PT09PT09PT09PT09PT09PT09IOWFseeUqCBQcml2YXRlIEhlbHBlcnMgPT09PT09PT09PT09PT09PT09PT09ICovCgoKCi8qKiDmib7nrKzkuIDlgIvlrZDlhYPntKDvvIjnlKggbG9jYWxOYW1lIOaIliBub2RlTmFtZe+8jOavlOWwjeWtl+mdoiAiSVFLQiIg562J77yJICovCgpwcml2YXRlIHN0YXRpYyBFbGVtZW50IGZpcnN0Q2hpbGRFbGVtZW50QnlMb2NhbE5hbWUoRWxlbWVudCBwYXJlbnQsIFN0cmluZyBsb2NhbCkgewoKICAgIGZvciAoTm9kZSBuID0gcGFyZW50LmdldEZpcnN0Q2hpbGQoKTsgbiAhPSBudWxsOyBuID0gbi5nZXROZXh0U2libGluZygpKSB7CgogICAgICAgIGlmIChuLmdldE5vZGVUeXBlKCkgPT0gTm9kZS5FTEVNRU5UX05PREUpIHsKCiAgICAgICAgICAgIFN0cmluZyBsbiA9IG4uZ2V0TG9jYWxOYW1lKCk7IC8vIOWPr+iDveeCuiBudWxs77yI54ShIG5hbWVzcGFjZe+8iQoKICAgICAgICAgICAgU3RyaW5nIG5uID0gbi5nZXROb2RlTmFtZSgpOyAgLy8g5Y+v6IO95pivICJkaWZmZ3I6ZGlmZmdyYW0iCgogICAgICAgICAgICBpZiAobG9jYWwuZXF1YWxzKG5uKSB8fCBsb2NhbC5lcXVhbHNJZ25vcmVDYXNlKGxuKSkgewoKICAgICAgICAgICAgICAgIHJldHVybiAoRWxlbWVudCkgbjsKCiAgICAgICAgICAgIH0KCiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gbnVsbDsKCn0KCgoKLyoqIOWPluafkOWAiyB0YWcg55qE5paH5a2X5YC877yIQXhpcyDnm7jlrrnvvJvpgb/lhY3nlKggZ2V0VGV4dENvbnRlbnQoKS90b1N0cmluZygp77yJICovCgpwcml2YXRlIHN0YXRpYyBTdHJpbmcgZ2V0Q2hpbGRUZXh0KEVsZW1lbnQgcGFyZW50LCBTdHJpbmcgdGFnKSB7CgogICAgTm9kZUxpc3QgbmwgPSBwYXJlbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUodGFnKTsKCiAgICBpZiAobmwgPT0gbnVsbCB8fCBubC5nZXRMZW5ndGgoKSA9PSAwKSByZXR1cm4gIiI7CgogICAgcmV0dXJuIGdldE5vZGVUZXh0Q29tcGF0KG5sLml0ZW0oMCkpLnRyaW0oKTsKCn0KCgoKLyoqIOebuOWuuSBBeGlzIE1lc3NhZ2VFbGVtZW50IOeahOWPluaWh+Wtl++8muaLvCBURVhUX05PREUgLyBDREFUQSAqLwoKcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIGdldE5vZGVUZXh0Q29tcGF0KE5vZGUgbm9kZSkgewoKICAgIGlmIChub2RlID09IG51bGwpIHJldHVybiAiIjsKCiAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKCiAgICBOb2RlTGlzdCBjaGlsZHJlbiA9IG5vZGUuZ2V0Q2hpbGROb2RlcygpOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY2hpbGRyZW4uZ2V0TGVuZ3RoKCk7IGkrKykgewoKICAgICAgICBOb2RlIGMgPSBjaGlsZHJlbi5pdGVtKGkpOwoKICAgICAgICBzaG9ydCB0ID0gYy5nZXROb2RlVHlwZSgpOwoKICAgICAgICBpZiAodCA9PSBOb2RlLlRFWFRfTk9ERSB8fCB0ID09IE5vZGUuQ0RBVEFfU0VDVElPTl9OT0RFKSB7CgogICAgICAgICAgICBzYi5hcHBlbmQoYy5nZXROb2RlVmFsdWUoKSk7CgogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7Cgp9Cg==