在 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 这样的更多操作了