java - 解析xml文件,重命名标签并再次保存

标签 java xml parsing xml-parsing

我有一个相当大的 xml 文件,需要更改其中的一些内容,这是它的外观片段

<CMPDN>
<ROOT_PRODUKTE>
    <PRODUKT name="00010000040">
        <BEZIEHUNGEN>
            <BEZIEHUNGSTYP name="ZBH2BIKE">
                <PRODUKT name="78104974100" id="1001049290">
                    <RELATEDARTICLES>
                        <RELATEDARTICLE name="F6101M0" id="1000264817"/>
                    </RELATEDARTICLES>
                </PRODUKT>
            </BEZIEHUNGSTYP>
        </BEZIEHUNGEN>
    </PRODUKT>
</ROOT_PRODUKTE>

正如所说,这只是一个片段。 我使用 jxb 将 xsd 文件转换为 java 类,所以现在我可以修改数据了。

当我想重命名其中一个标签而不仅仅是任何标签时,问题就出现了。我想将内部 PRODUKT 标签重命名为 PRODUKT_FIT,如下所示:

<CMPDN>
<ROOT_PRODUKTE>
    <PRODUKT name="00010000040">
        <BEZIEHUNGEN>
            <BEZIEHUNGSTYP name="ZBH2BIKE">
                <PRODUKT_FIT name="78104974100" id="1001049290">
                    <RELATEDARTICLES>
                        <RELATEDARTICLE name="F6101M0" id="1000264817"/>
                    </RELATEDARTICLES>
                </PRODUKT_FIT>
            </BEZIEHUNGSTYP>
        </BEZIEHUNGEN>
    </PRODUKT>
</ROOT_PRODUKTE>

现在我尝试创建 3 个新类 BEZIEHUNGEN , BEZIEHUNGSTYPPRODUKT_FIT我更改了 PRDUKT 类的定义,如下所示

public class PRODUKT {
@XmlElements({
    @XmlElement(name = "ATTRIBUTE", type = ATTRIBUTE.class),
    @XmlElement(name = "BEZIEHUNGEN", type = io.github.sumsar1812.models.write.BEZIEHUNGEN.class),
    @XmlElement(name = "BEZIEHUNGEN", type = BEZIEHUNGEN.class),
    @XmlElement(name = "KLASSEN", type = KLASSEN.class),
    @XmlElement(name = "LAENDER", type = LAENDER.class),
    @XmlElement(name = "MEDIENELEMENTE", type = MEDIENELEMENTE.class),
    @XmlElement(name = "PREISE", type = PREISE.class),
    @XmlElement(name = "RELATEDARTICLES", type = RELATEDARTICLES.class),
    @XmlElement(name = "TEXTELEMENTE", type = TEXTELEMENTE.class),
    @XmlElement(name = "PARENT_NAME", type = PARENTNAME.class),
})

其中 models.write 包包含新的 3 个类。

PRODUKT_FIT 类如下所示:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
        "attributeOrBEZIEHUNGENOrKLASSEN"
})
@XmlRootElement(name = "PRODUKT_FIT")
public class PRODUKT_FIT {

    @XmlElements({
            @XmlElement(name = "ATTRIBUTE", type = ATTRIBUTE.class),
            @XmlElement(name = "BEZIEHUNGEN", type = io.github.sumsar1812.models.write.BEZIEHUNGEN.class),
            @XmlElement(name = "KLASSEN", type = KLASSEN.class),
            @XmlElement(name = "LAENDER", type = LAENDER.class),
            @XmlElement(name = "MEDIENELEMENTE", type = MEDIENELEMENTE.class),
            @XmlElement(name = "PREISE", type = PREISE.class),
            @XmlElement(name = "RELATEDARTICLES", type = RELATEDARTICLES.class),
            @XmlElement(name = "TEXTELEMENTE", type = TEXTELEMENTE.class)
    })
    protected List<Object> attributeOrBEZIEHUNGENOrKLASSEN;
    @XmlAttribute(name = "name", required = true)
    protected String name;
/*getters and setters omitted */

据我现在所见,产品应该能够包含 BEZIEHUNGEN 的读取值和 BEZIEHUNGEN 的写入值(包含 BEZIEHUNGSTYP 列表和每个包含 PRODUKT_FIT 列表的列表)

重新格式化一些数据后,我可以使用调试器看到数据格式正确(RELATEDARTICLE 是可选的,这就是 attributeOrBEZIEHUNGENOrKLASSEN 为空的原因)

debugging confirmation

但问题是,当我尝试将类保存回文件(如下所示)时,它仍然命名为 PRODUKT 而不是 PRODUKT_FIT,我对数据所做的所有其他更改都已正确保存。知道这是为什么吗?

public void passRoot(String newFilename, CMPDN root) {
    try {
        File file = new File(newFilename);
        JAXBContext jaxbContext = JAXBContext.newInstance(CMPDN.class);
        Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
        jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        jaxbMarshaller.marshal(root, file);

    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

编辑 所以我尝试使用 XSLT 并取得了一些成功,这是我现在的样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="CMPDN/ROOT_PRODUKTE/PRODUKT/BEZIEHUNGEN/BEZIEHUNGSTYP/PRODUKT">
    <PRODUKT_FIT>
        <xsl:apply-templates select="@*|node()" />
        <xsl:value-of select="."/>

    </PRODUKT_FIT>
</xsl:template>

这有效,但它在 /RELATEDARTICLES> 下面添加了空行和</PRODUKT_FIT>所以我尝试添加 <xsl:strip-space elements="*"/>但这使它全部变成一行,所以我添加了 omit-xml-declaration="yes" indent="yes"到 xsl:output 但这只是部分修复了它,因为现在看起来像这样:

xml file 它没有以前的格式,但不知道为什么?

最佳答案

在样式表文件中使用它:

    <xsl:output method="xml" omit-xml-declaration="yes"
        indent="yes" encoding="utf-8" xslt:indent-amount="3"
        xmlns:xslt="http://xml.apache.org/xslt" />
    <xsl:strip-space elements="*" />

当然,您可以根据需要配置indent-amount

参见Apache Xalan欲了解更多信息。

关于java - 解析xml文件,重命名标签并再次保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53710904/

相关文章:

java - Project Reactor 将发布者一分为二,至少有两个订阅者

javascript - 如何从以下 xml 制作层次结构数组?

c# - 基于 XML 数据创建动态 linq-XML

ios - 在 Swift 中使用 Codable 将具有不同键的 JSON 解析为同一对象

parsing - 使用 yyparse() 制作两遍汇编程序?

java - 我们可以在 BlueMix 上创建一个 Java 应用程序并安排它每天运行吗?

java - 按两个 double 值对对象数组进行排序

java - Log4J 自定义字段

java - 使用任意 xml 文件验证 xml

python - 正则表达式解析格式良好的多行数据字典