在 StaxEventItemReader 中获取属性名称和值形式 XML
Get Attribute name and value form XML in StaxEventItemReader
为了一个看似简单的问题兜兜转转
我有一个 XML,它只包含没有值的标签(只有属性)。
我想用 StaxEventItemReader 遍历这个 XML 但我不能。
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE dataset>
<dataset>
<table_row id="3944552" code_a="N" code_b="232" num_abc="[NULL]" sexe="M" date_nais="1959-11-15" />
<table_row id="3944553" code_a="[NULL]" code_b="[NULL]" num_abc="[NULL]" sexe="F" date_nais="1920-05-10" />
</dataset>
还有 reader :
private StaxEventItemReader<TableRow> createXmlReader(Resource source) throws Exception {
StaxEventItemReader<TableRow> reader = new StaxEventItemReader<>();
reader.setResource(source);
reader.setFragmentRootElementName("table_row");
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setClassesToBeBound(TableRow.class);
reader.setUnmarshaller(jaxb2Marshaller);
reader.afterPropertiesSet();
return reader;
}
我确实在尝试在我的 reader 的输出端(以及在我的处理器的输入端)获取此内容图像中的一个对象,其中包含一个包含每个属性/值的 MAP
@Setter
@Getter
public class TableRow {
private Map<String, String> mapChampValeurs;
}
我尝试使用适配器,但我看不到如何实现它(我使用 @XmlJavaTypeAdapter() 但我从未输入我的适配器)
你知道我该怎么做吗?
编辑 1
我尝试添加一个适配器来转换地图中的所有属性
public class TableRowXmlAdapter extends XmlAdapter<Object, TableRow> {
private static final Logger LOGGER = LoggerFactory.getLogger(TableRowXmlAdapter.class);
@Override
public TableRow unmarshal(Object v) throws Exception {
LOGGER.info("***** INTO ROW ADAPTER ****");
Element element = (Element) v;
Map<String, String> properties = new LinkedHashMap<>();
NamedNodeMap attributes = element.getAttributes();
for (int i = attributes.getLength() - 1; i >= 0; i--) {
Node node = attributes.item(i);
properties.put(node.getNodeName(), node.getNodeValue());
}
TableRow tableRow = new TableRow();
tableRow.setMapChampValeurs(properties);
return tableRow;
}
我在 StaxEventItemReader 中声明它:
private StaxEventItemReader<TableRow> createXmlReader(Resource source) throws Exception {
StaxEventItemReader reader = new StaxEventItemReader();
reader.setResource(source);
reader.setFragmentRootElementName(ROOT_ELEMENT);
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
TableRowXmlAdapter tableRowXmlAdapter = new TableRowXmlAdapter();
jaxb2Marshaller.setAdapters(tableRowXmlAdapter);
jaxb2Marshaller.setClassesToBeBound(TableRow.class);
reader.setUnmarshaller(jaxb2Marshaller);
reader.afterPropertiesSet();
return reader;
}
但是当我调试它时,我从来没有进入我的适配器并且有一个异常:
Caused by: com.sun.istack.internal.SAXParseException2; lineNumber: 4; columnNumber: 94; élément inattendu (URI : "", local : "table_row"). Les éléments attendus sont (none)
lineNumber和columnNumber都表示最后一个字符刚好在“/>”自闭标签之后的位置
有关信息,我找到了带有@XmlAnyAttribute 注释的解决方案
@XmlAnyAttribute
private Map<QName, String> mapChampValeurs;
有了那个注解,就不需要像 Adapter 这样的更多操作了
为了一个看似简单的问题兜兜转转
我有一个 XML,它只包含没有值的标签(只有属性)。
我想用 StaxEventItemReader 遍历这个 XML 但我不能。
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE dataset>
<dataset>
<table_row id="3944552" code_a="N" code_b="232" num_abc="[NULL]" sexe="M" date_nais="1959-11-15" />
<table_row id="3944553" code_a="[NULL]" code_b="[NULL]" num_abc="[NULL]" sexe="F" date_nais="1920-05-10" />
</dataset>
还有 reader :
private StaxEventItemReader<TableRow> createXmlReader(Resource source) throws Exception {
StaxEventItemReader<TableRow> reader = new StaxEventItemReader<>();
reader.setResource(source);
reader.setFragmentRootElementName("table_row");
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setClassesToBeBound(TableRow.class);
reader.setUnmarshaller(jaxb2Marshaller);
reader.afterPropertiesSet();
return reader;
}
我确实在尝试在我的 reader 的输出端(以及在我的处理器的输入端)获取此内容图像中的一个对象,其中包含一个包含每个属性/值的 MAP
@Setter
@Getter
public class TableRow {
private Map<String, String> mapChampValeurs;
}
我尝试使用适配器,但我看不到如何实现它(我使用 @XmlJavaTypeAdapter() 但我从未输入我的适配器)
你知道我该怎么做吗?
编辑 1
我尝试添加一个适配器来转换地图中的所有属性
public class TableRowXmlAdapter extends XmlAdapter<Object, TableRow> {
private static final Logger LOGGER = LoggerFactory.getLogger(TableRowXmlAdapter.class);
@Override
public TableRow unmarshal(Object v) throws Exception {
LOGGER.info("***** INTO ROW ADAPTER ****");
Element element = (Element) v;
Map<String, String> properties = new LinkedHashMap<>();
NamedNodeMap attributes = element.getAttributes();
for (int i = attributes.getLength() - 1; i >= 0; i--) {
Node node = attributes.item(i);
properties.put(node.getNodeName(), node.getNodeValue());
}
TableRow tableRow = new TableRow();
tableRow.setMapChampValeurs(properties);
return tableRow;
}
我在 StaxEventItemReader 中声明它:
private StaxEventItemReader<TableRow> createXmlReader(Resource source) throws Exception {
StaxEventItemReader reader = new StaxEventItemReader();
reader.setResource(source);
reader.setFragmentRootElementName(ROOT_ELEMENT);
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
TableRowXmlAdapter tableRowXmlAdapter = new TableRowXmlAdapter();
jaxb2Marshaller.setAdapters(tableRowXmlAdapter);
jaxb2Marshaller.setClassesToBeBound(TableRow.class);
reader.setUnmarshaller(jaxb2Marshaller);
reader.afterPropertiesSet();
return reader;
}
但是当我调试它时,我从来没有进入我的适配器并且有一个异常:
Caused by: com.sun.istack.internal.SAXParseException2; lineNumber: 4; columnNumber: 94; élément inattendu (URI : "", local : "table_row"). Les éléments attendus sont (none)
lineNumber和columnNumber都表示最后一个字符刚好在“/>”自闭标签之后的位置
有关信息,我找到了带有@XmlAnyAttribute 注释的解决方案
@XmlAnyAttribute
private Map<QName, String> mapChampValeurs;
有了那个注解,就不需要像 Adapter 这样的更多操作了