我有一个带有嵌套元素和重复标签的 XML。例如:
<person>
<name>Rama</name>
<age>27</age>
<gender>male</gender>
<address>
<doornumber>234</doornumber>
<street>Kanon</street>
<city>Hyderabad</city>
</address>
<qualification>
<degree>M.Sc</degree>
<specialisation>Maths</specialisation>
</qualification>
<qualification>
<degree>B.E.</degree>
<specialisation>Electrical</specialisation>
</qualification>
</person>
现在我想要一个 API 将此 XML 转换为 Java 中的 map 的 map :
{name="Rama",age="27",gender="male",address={doornumber=234,street="Kanon",city="Hyderabad"},qualification=[{degree="M.Sc",specialisation="Maths"},{degree="B.E.",specialisation="Electrical"}]}
我知道我们可以使用 XStream API 来实现这一点。在这里,我只想知道使用 XStream 是否有任何缺点,以及是否存在任何其他更好的 Java API 来实现这一点。有什么建议吗?
注意:这应该以通用方式完成,即 Java API 应该适用于任何 XML,而不仅仅是上面的 XML。
最佳答案
虽然已经很晚了。但是我已经为 XStream API 编写了一个自定义的 MapEntryConverter,它可以处理任何复杂的 XML 数据,无论它有多深。甚至它会支持重复的标签名称(将存储为 ArrayList)。
XStream xStream = new XStream(new DomDriver());
xStream.registerConverter(new MapEntryConverter());
xStream.alias("xml", java.util.Map.class);
// from XML, convert back to map
Map<String, List<Object>> map = (Map<String, List<Object>>) xStream.fromXML(xmlData);
/*System.out.println("MAP: \n" + map.entrySet().toString());*/
String xml = xStream.toXML(map);
/*System.out.println("XML: \n"+xml);*/
MapEntryConverter.java
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class MapEntryConverter implements Converter{
@SuppressWarnings("rawtypes")
public boolean canConvert(Class clazz) {
return AbstractMap.class.isAssignableFrom(clazz);
}
@SuppressWarnings({ "unchecked" })
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
AbstractMap<String, List<?>> map = (AbstractMap<String, List<?>>) value;
List<Map<String, ?>> list = (List<Map<String, ?>>) map.get("xml");
for( Map<String, ?> maps: list ) {
for( Entry<String, ?> entry: maps.entrySet() ) {
mapToXML(writer, entry);
}
}
}
@SuppressWarnings("unchecked")
private void mapToXML(HierarchicalStreamWriter writer, Entry<String, ?> entry) {
writer.startNode(entry.getKey());
if( entry.getValue() instanceof String ) {
writer.setValue(entry.getValue().toString());
}else if( entry.getValue() instanceof ArrayList ) {
List<?> list = (List<?>) entry.getValue();
for( Object object: list ) {
Map<String, ?> map = (Map<String, ?>) object;
for( Entry<String, ?> entryS: map.entrySet() ) {
mapToXML(writer, entryS);
}
}
}
writer.endNode();
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
map = xmlToMap(reader, new HashMap<String, List<Object>>());
return map;
}
private Map<String, List<Object>> xmlToMap(HierarchicalStreamReader reader, Map<String, List<Object>> map) {
List<Object> list = new ArrayList<Object>();
while(reader.hasMoreChildren()) {
reader.moveDown();
if( reader.hasMoreChildren() ) {
list.add(xmlToMap(reader, new HashMap<String, List<Object>>()));
}else {
Map<String, Object> mapN = new HashMap<String, Object>();
mapN.put(reader.getNodeName(), reader.getValue());
list.add(mapN);
}
reader.moveUp();
}
map.put(reader.getNodeName(), list);
return map;
}
}
请注意,Map 中的每个值如果有任何子项,都将存储为一个列表。根据我的说法,解码部分非常整洁。我会在空闲时间完善和简化编码部分。
输入数据应在如下所示的 xml 标记中提供。
<xml>
<person>
<name>Rama</name>
<age>27</age>
<gender>male</gender>
<address>
<doornumber>234</doornumber>
<street>Kanon</street>
<city>Hyderabad</city>
</address>
<qualification>
<degree>M.Sc</degree>
<specialisation>Maths</specialisation>
</qualification>
<qualification>
<degree>B.E.</degree>
<specialisation>Electrical</specialisation>
</qualification>
</person>
</xml>
将我的输出与您的预期输出进行比较时,有一点变化。重复的键值不会合并为一个数组,而是属于单独的列表。
关于java - 将 XML 转换为嵌套 map 的 Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22226116/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.