2020年11月22日 星期日

無法透過XPath處理的XML字串

 要處理的XML字串如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="AB01"><property name="output"><map><entry><key><value>ID</value></key><value>01</value></entry><entry><key><value>ACNO</value></key><value></value></entry><entry><key><value>AMT</value></key><value></value></entry></map></property></bean></beans>


因為無法使用以下這種javax.xml.xpath的方式處理
XPathExpression expression = xPath.compile("//beans//bean//property[@name='output']");

所以改用org.w3c.dom的方式處理
Element eElement = (Element) nNode;
eElement.getElementsByTagName("entry").item(0).getTextContent());
會抓出ID01,再自己substring處理
雖然可以達到目的,但感覺應該有更好的方式

經網友指點,亦可使用以下方式處理eElement.getElementsByTagName("entry").item(0).getChildNodes().item(0).getTextContent()
=>可以取得ID

eElement.getElementsByTagName("entry").item(0).getChildNodes().item(1).getTextContent()
=>可以取得01

應該也可以使用JAXB,但是沒用過JAXB,不熟
日後再研究

Servlet輸出中文有問號???

已經確認資料來源編碼沒問題,log也可以正常顯示中文字
但Servlet頁面一直顯示問號???

解決方式:
需在response.getWriter()的之前加入以下設定
response.setContentType("text/html;charset=UTF-8");
如果使用Big5加入
response.setContentType("text/html;charset=Big5");

xml來源是Big5編碼的處理方式

InputStream xmlInputStream = new ByteArrayInputStream(resXmlString.getBytes("Big5"));

DocumentBuilderFactory xmlFactory = DocumentBuilderFactory.newInstance();

DocumentBuilder xmlBuilder = xmlFactory.newDocumentBuilder();

InputSource is = new InputSource(xmlInputStream);

is.setEncoding("Big5");  

Document xmldoc = xmlBuilder.parse(is);


備註:
不設定setEncoding會遇到的錯誤訊息是
英文:Invalid byte 1 of 1-byte UTF-8 sequence
中文:1-byte UTF-8 序列的無效位元組1

2020年11月18日 星期三

-Dfile.encoding 指定 JVM 預設編碼

 https://openhome.cc/Gossip/Encoding/JVMEncoding.html

有些 API 若不指定編碼,通常會使用 JVM 預設編碼,預設會與作業系統預設編碼相同,像是 String 建構式、 getBytes() 方法或這邊看到的 FileReader 等(其他還有 java.iojava.utiljava.net 等套件中的一些 API),可以使用 Charset.defaultCharset() 取得預設編碼。

在啟動 JVM 時,其實可以使用 -Dfile.encoding 指定 JVM 預設編碼,例如:

C:\workspace>java -Dfile.encoding=UTF-8 cc.openhome.Main

getBytes() encodes a String into a byte array using the platform's default charset
https://www.baeldung.com/string/get-bytes

https://openhome.cc/Gossip/Encoding/String.html

ref:
https://openhome.cc/Gossip/Encoding/index.html

https://www.javaworld.com.tw/jute/post/view?bid=21&id=282136&tpg=1&ppg=1&sty=1&age=0#282136

https://stackoverflow.com/questions/12659417/why-does-javas-string-getbytes-uses-iso-8859-1

https://docs.oracle.com/javase/tutorial/i18n/text/string.html

2020年11月4日 星期三

XML XPathExpression

https://stackoverflow.com/questions/15421847/retrieving-attributes-and-values-of-child-nodes-of-an-xml-element-in-java

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;


    final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));

    final XPath xPath = XPathFactory.newInstance().newXPath();

    final XPathExpression expression = xPath.compile("//course[@name='AdvancedAlgorithm']//Teacher");


    final NodeList nodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);


    for (int i = 0; i < nodeList.getLength(); ++i) {

        System.out.println(((Element)nodeList.item(i)).getAttribute("name"));

    }