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) {
for (MessageElement me : anyArr) {
NodeList dgs = me.getElementsByTagNameNS("*", "diffgram");
if (dgs != null && dgs.getLength() > 0) { diffgram = (Element) dgs.item(0); 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) 抓每一筆 <TreeAllKB> row(schema 在外層,這裡才是資料)
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 = childText(row, "ifq_sid");
String name = childText(row, "sfq_name");
// 有需要也能拿:ifq_no / iis_index / dmodi_time
// String no = childText(row, "ifq_no");
// String idx = childText(row, "iis_index");
// String modi = childText(row, "dmodi_time");
if (!sid.isBlank()) {
map.put(sid.trim(), name.trim());
}
}
// 小小稽核
LOGGER.info("getTitleData: rows={}, mapped={}", rows.getLength(), map.size());
return map;
}
/* ------------ Helpers(Axis 相容、避開 getTextContent) ------------ */
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
String nn = n.getNodeName(); // 可能是 prefix:name
if (local.equals(nn) || local.equalsIgnoreCase(ln)) return (Element) n;
}
}
return null;
}
private static String childText(Element parent, String tag) {
NodeList nl = parent.getElementsByTagName(tag);
if (nl == null || nl.getLength() == 0) return "";
return nodeTextCompat(nl.item(0)).trim();
}
private static String nodeTextCompat(Node node) {
if (node == null) return "";
StringBuilder sb = new StringBuilder();
NodeList cs = node.getChildNodes();
for (int i = 0; i < cs.getLength(); i++) {
Node c = cs.item(i);
short t = c.getNodeType();
if (t == Node.TEXT_NODE || t == Node.CDATA_SECTION_NODE) {
sb.append(c.getNodeValue());
}
}
return sb.toString();
}
aW1wb3J0IG9yZy5hcGFjaGUuYXhpcy5tZXNzYWdlLk1lc3NhZ2VFbGVtZW50OwoKaW1wb3J0IG9yZy53M2MuZG9tLio7CgoKCmltcG9ydCBqYXZhLnV0aWwuTGlua2VkSGFzaE1hcDsKCgoKcHVibGljIExpbmtlZEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+IGdldFRpdGxlRGF0YShpbnQgaWZ0U2lkICwgU3RyaW5nIHVzZXJUeXBlKSB0aHJvd3MgRXhjZXB0aW9uIHsKCiAgICBMaW5rZWRIYXNoTWFwPFN0cmluZyxTdHJpbmc+IG1hcCA9IG5ldyBMaW5rZWRIYXNoTWFwPD4oKTsKCgoKICAgIElRS0JfWE1MU29hcFByb3h5IHNlcnZpY2UgPSBuZXcgSVFLQl9YTUxTb2FwUHJveHkoKTsKCiAgICBXc0dldFRyZWVBbGxLQlJlc3BvbnNlV3NHZXRUcmVlQWxsS0JSZXN1bHQgcmVzdWx0ID0KCiAgICAgICAgICAgIHNlcnZpY2Uud3NHZXRUcmVlQWxsS0Ioc3RyVmFsaWRDb2RlLCAxLCBjaGFubmVsTWFwLmdldCh1c2VyVHlwZSksIGlmdFNpZCwgMSk7CgoKCiAgICBNZXNzYWdlRWxlbWVudFtdIGFueUFyciA9IHJlc3VsdC5nZXRfYW55KCk7CgogICAgaWYgKGFueUFyciA9PSBudWxsIHx8IGFueUFyci5sZW5ndGggPT0gMCkgewoKICAgICAgICBMT0dHRVIud2FybigiZ2V0VGl0bGVEYXRhOiBnZXRfYW55KCkg54K656m6Iik7CgogICAgICAgIHJldHVybiBtYXA7CgogICAgfQoKCgogICAgLy8gMSkg5om+IGRpZmZncmFt77yI5b+955WlIHhzOnNjaGVtYe+8iQoKICAgIEVsZW1lbnQgZGlmZmdyYW0gPSBudWxsOwoKICAgIGZvciAoTWVzc2FnZUVsZW1lbnQgbWUgOiBhbnlBcnIpIHsKCiAgICAgICAgU3RyaW5nIGxuID0gbWUuZ2V0TG9jYWxOYW1lKCk7CgogICAgICAgIGlmICgiZGlmZmdyYW0iLmVxdWFsc0lnbm9yZUNhc2UobG4pKSB7IGRpZmZncmFtID0gbWU7IGJyZWFrOyB9CgogICAgfQoKICAgIGlmIChkaWZmZ3JhbSA9PSBudWxsKSB7CgogICAgICAgIGZvciAoTWVzc2FnZUVsZW1lbnQgbWUgOiBhbnlBcnIpIHsKCiAgICAgICAgICAgIE5vZGVMaXN0IGRncyA9IG1lLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoIioiLCAiZGlmZmdyYW0iKTsKCiAgICAgICAgICAgIGlmIChkZ3MgIT0gbnVsbCAmJiBkZ3MuZ2V0TGVuZ3RoKCkgPiAwKSB7IGRpZmZncmFtID0gKEVsZW1lbnQpIGRncy5pdGVtKDApOyBicmVhazsgfQoKICAgICAgICB9CgogICAgfQoKICAgIGlmIChkaWZmZ3JhbSA9PSBudWxsKSB7CgogICAgICAgIExPR0dFUi53YXJuKCJnZXRUaXRsZURhdGE6IOaJvuS4jeWIsCBkaWZmZ3I6ZGlmZmdyYW0iKTsKCiAgICAgICAgcmV0dXJuIG1hcDsKCiAgICB9CgoKCiAgICAvLyAyKSDpgLLliLAgSVFLQu+8iOacieS6m+WbnuaHieWPr+iDveaykuaciemAmeWxpO+8jOWJh+eUqCBkaWZmZ3JhbSDmnKzouqvvvIkKCiAgICBFbGVtZW50IGRhdGFSb290ID0gZmlyc3RDaGlsZEVsZW1lbnRCeUxvY2FsTmFtZShkaWZmZ3JhbSwgIklRS0IiKTsKCiAgICBpZiAoZGF0YVJvb3QgPT0gbnVsbCkgZGF0YVJvb3QgPSBkaWZmZ3JhbTsKCgoKICAgIC8vIDMpIOaKk+avj+S4gOethiA8VHJlZUFsbEtCPiByb3fvvIhzY2hlbWEg5Zyo5aSW5bGk77yM6YCZ6KOh5omN5piv6LOH5paZ77yJCgogICAgTm9kZUxpc3Qgcm93cyA9IGRhdGFSb290LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJUcmVlQWxsS0IiKTsKCiAgICBpZiAocm93cyA9PSBudWxsIHx8IHJvd3MuZ2V0TGVuZ3RoKCkgPT0gMCkgewoKICAgICAgICBMT0dHRVIud2FybigiZ2V0VGl0bGVEYXRhOiBJUUtCIOWFp+aykuaciSBUcmVlQWxsS0IiKTsKCiAgICAgICAgcmV0dXJuIG1hcDsKCiAgICB9CgoKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IHJvd3MuZ2V0TGVuZ3RoKCk7IGkrKykgewoKICAgICAgICBFbGVtZW50IHJvdyA9IChFbGVtZW50KSByb3dzLml0ZW0oaSk7CgoKCiAgICAgICAgLy8g5Zyo44CM5ZCM5LiA5YCLIHJvdyDoo6HjgI3lj5bmrITkvY3vvIzpgb/lhY3kuqTpjK8KCiAgICAgICAgU3RyaW5nIHNpZCAgID0gY2hpbGRUZXh0KHJvdywgImlmcV9zaWQiKTsKCiAgICAgICAgU3RyaW5nIG5hbWUgID0gY2hpbGRUZXh0KHJvdywgInNmcV9uYW1lIik7CgogICAgICAgIC8vIOaciemcgOimgeS5n+iDveaLv++8mmlmcV9ubyAvIGlpc19pbmRleCAvIGRtb2RpX3RpbWUKCiAgICAgICAgLy8gU3RyaW5nIG5vICAgID0gY2hpbGRUZXh0KHJvdywgImlmcV9ubyIpOwoKICAgICAgICAvLyBTdHJpbmcgaWR4ICAgPSBjaGlsZFRleHQocm93LCAiaWlzX2luZGV4Iik7CgogICAgICAgIC8vIFN0cmluZyBtb2RpICA9IGNoaWxkVGV4dChyb3csICJkbW9kaV90aW1lIik7CgoKCiAgICAgICAgaWYgKCFzaWQuaXNCbGFuaygpKSB7CgogICAgICAgICAgICBtYXAucHV0KHNpZC50cmltKCksIG5hbWUudHJpbSgpKTsKCiAgICAgICAgfQoKICAgIH0KCgoKICAgIC8vIOWwj+Wwj+eoveaguAoKICAgIExPR0dFUi5pbmZvKCJnZXRUaXRsZURhdGE6IHJvd3M9e30sIG1hcHBlZD17fSIsIHJvd3MuZ2V0TGVuZ3RoKCksIG1hcC5zaXplKCkpOwoKICAgIHJldHVybiBtYXA7Cgp9CgoKCi8qIC0tLS0tLS0tLS0tLSBIZWxwZXJz77yIQXhpcyDnm7jlrrnjgIHpgb/plosgZ2V0VGV4dENvbnRlbnTvvIkgLS0tLS0tLS0tLS0tICovCgoKCnByaXZhdGUgc3RhdGljIEVsZW1lbnQgZmlyc3RDaGlsZEVsZW1lbnRCeUxvY2FsTmFtZShFbGVtZW50IHBhcmVudCwgU3RyaW5nIGxvY2FsKSB7CgogICAgZm9yIChOb2RlIG4gPSBwYXJlbnQuZ2V0Rmlyc3RDaGlsZCgpOyBuICE9IG51bGw7IG4gPSBuLmdldE5leHRTaWJsaW5nKCkpIHsKCiAgICAgICAgaWYgKG4uZ2V0Tm9kZVR5cGUoKSA9PSBOb2RlLkVMRU1FTlRfTk9ERSkgewoKICAgICAgICAgICAgU3RyaW5nIGxuID0gbi5nZXRMb2NhbE5hbWUoKTsgICAvLyDlj6/og73ngrogbnVsbAoKICAgICAgICAgICAgU3RyaW5nIG5uID0gbi5nZXROb2RlTmFtZSgpOyAgICAvLyDlj6/og73mmK8gcHJlZml4Om5hbWUKCiAgICAgICAgICAgIGlmIChsb2NhbC5lcXVhbHMobm4pIHx8IGxvY2FsLmVxdWFsc0lnbm9yZUNhc2UobG4pKSByZXR1cm4gKEVsZW1lbnQpIG47CgogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIG51bGw7Cgp9CgoKCnByaXZhdGUgc3RhdGljIFN0cmluZyBjaGlsZFRleHQoRWxlbWVudCBwYXJlbnQsIFN0cmluZyB0YWcpIHsKCiAgICBOb2RlTGlzdCBubCA9IHBhcmVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWcpOwoKICAgIGlmIChubCA9PSBudWxsIHx8IG5sLmdldExlbmd0aCgpID09IDApIHJldHVybiAiIjsKCiAgICByZXR1cm4gbm9kZVRleHRDb21wYXQobmwuaXRlbSgwKSkudHJpbSgpOwoKfQoKCgpwcml2YXRlIHN0YXRpYyBTdHJpbmcgbm9kZVRleHRDb21wYXQoTm9kZSBub2RlKSB7CgogICAgaWYgKG5vZGUgPT0gbnVsbCkgcmV0dXJuICIiOwoKICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwoKICAgIE5vZGVMaXN0IGNzID0gbm9kZS5nZXRDaGlsZE5vZGVzKCk7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjcy5nZXRMZW5ndGgoKTsgaSsrKSB7CgogICAgICAgIE5vZGUgYyA9IGNzLml0ZW0oaSk7CgogICAgICAgIHNob3J0IHQgPSBjLmdldE5vZGVUeXBlKCk7CgogICAgICAgIGlmICh0ID09IE5vZGUuVEVYVF9OT0RFIHx8IHQgPT0gTm9kZS5DREFUQV9TRUNUSU9OX05PREUpIHsKCiAgICAgICAgICAgIHNiLmFwcGVuZChjLmdldE5vZGVWYWx1ZSgpKTsKCiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKCn0K