我不确定这是否可行,但我正在编写一个将数据从数据库转换为 XML 的程序。问题是数据库中的某些值具有特殊字符。我们将典型的 XML 特殊字符硬编码在映射中,但我们希望有一个可在运行时读取的可配置 XML 映射文件。
<mapping source="ÿ" target="ÿ"/>
<mapping source="þ" target="þ"/>
<mapping source="ý" target="ý"/>
<mapping source="ü" target="ü"/>
<mapping source="û" target="û"/>
<mapping source="ú" target="ú"/>
我们使用 xstream 来读取 XML。
public class CharMapping {
private static final String CHAR_MAPPING_FILE = "char_mapping.xml";
private static final String XML_ROOT_ELEMENT = "mappings";
private static String readXmlFile(String filename) {
StringBuffer xmlContent = new StringBuffer();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(filename),"ISO-8859-1"))) {
String currentLine;
while ((currentLine = br.readLine()) != null) {
xmlContent.append(currentLine);
}
} catch (IOException e) {
e.printStackTrace();
}
return xmlContent.toString();
}
@SuppressWarnings("unchecked")
public static Map<String, String> getCharMapping() {
XStream xstream = new XStream();
xstream.alias(XML_ROOT_ELEMENT, java.util.Map.class);
xstream.registerConverter(new XMLConfigConverter("source", "target", null, null));
String xml = readXmlFile(CHAR_MAPPING_FILE);
Map<String, String> relationsMapping = (Map<String, String>) xstream.fromXML(xml);
return relationsMapping;
}
}
public class XMLConfigConverter implements Converter {
private String keyAttribute;
private String valueAttribute;
private String filterAttribute;
private String filterValue;
public XMLConfigConverter(String keyAttribute, String valueAttribute, String filterAttribute,
String filterValue) {
this.keyAttribute = keyAttribute;
this.valueAttribute = valueAttribute;
this.filterAttribute = filterAttribute;
this.filterValue = filterValue;
}
@SuppressWarnings("rawtypes")
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
@Override
public void marshal(Object arg0, HierarchicalStreamWriter writer, MarshallingContext context) {
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, String> map = new HashMap<String, String>();
while (reader.hasMoreChildren()) {
reader.moveDown();
if (reader.getNodeName().equals("mapping")) {
if (filterAttribute != null && filterValue != null) {
if (reader.getAttribute(filterAttribute).equals(filterValue)) {
putValueInMap(reader, map);
}
} else {
putValueInMap(reader, map);
}
}
reader.moveUp();
}
for(String charKey : map.keySet()) {
System.out.println("mapping: " + charKey + " - " + map.get(charKey)); }
return map;
}
private void putValueInMap(HierarchicalStreamReader reader, Map<String, String> map) {
String key = reader.getAttribute(keyAttribute);
String value = reader.getAttribute(valueAttribute);
System.out.println("Key: " + key + " - Value: " + value);
map.put(key, value);
}
}
输出为:
Key: ?¿ - Value: ÿ
Key: ?? - Value: ?
Key: ?½ - Value: ?
Key: ?¼ - Value: ü
Key: ?» - Value: û
Key: ?º - Value: ú
我知道从 XML 中提取 XML 的映射似乎有点奇怪。如果这是不可能的,是否有更好的解决方案的建议? CSV 映射会更好吗?
谢谢!
最佳答案
你的错误可能就在其中
new InputStreamReader(new FileInputStream(filename),"ISO-8859-1")))
您使用 Java 对文件进行解码,而不是让 XML 解析器进行解码。从你的输出证据来看,该文件似乎不是用 iso-8859-1 编码的,而是用 utf-8 编码的,如果你让 XML 解析器来进行解码,它可能会得到正确的结果。
我实际上并不了解 XStream,但 Javadoc 说有一个版本的 fromXML() 方法接受 File
作为输入。我建议您使用该版本的方法,这可能会正确解码,并删除您的 readXmlFile()
方法,该方法似乎出现错误。
当然,您可能仍然会遇到问题:也许文件以 UTF-8 编码,但将其编码声明为 ISO-8859-1。但我认为这一更改很有可能解决这个问题。
关于java - 如何在 Java 中从 XML 读取特殊字符的映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61261710/