简体   繁体   English

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

[英]Parse xml file, rename tag and save it again

I have a pretty big xml file and need to change some of it, this is a snippet of how it looks 我有一个很大的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>

This is as said just a snippet. 正如刚才所说的那样。 I used jxb to convert a xsd file into java classes so now I was able to modify the data. 我使用jxb将xsd文件转换为Java类,因此现在可以修改数据了。

The problem comes when I want to rename one of the tags, and not just any tag. 当我想重命名标签之一,而不仅仅是任何标签时,问题就来了。 I want to rename the inner PRODUKT tag to PRODUKT_FIT like this: 我想将内部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>

Now I have tried to create 3 new classes BEZIEHUNGEN , BEZIEHUNGSTYP and PRODUKT_FIT and I changed the definition for the class PRDUKT as seen here 现在,我尝试创建3个新类BEZIEHUNGENBEZIEHUNGSTYPPRODUKT_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),
})

where the models.write package contains the new 3 classes. 这里的models.write包包含新的3个类。

The PRODUKT_FIT class is shown below: 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 */

So as far as I can see now a produkt should be able to contain both the read values of BEZIEHUNGEN and write values of BEZIEHUNGEN(containing a list of BEZIEHUNGSTYP and each of those containing a list of PRODUKT_FIT) 因此,据我所知,一个产品应该既可以包含BEZIEHUNGEN的读取值,又可以包含BEZIEHUNGEN的写入值(包含一个BEZIEHUNGSTYP列表,每个包含一个PRODUKT_FIT列表)

After reformatting some data I can see with the debugger that the data is formated correctly(RELATEDARTICLE is optional so thats why attributeOrBEZIEHUNGENOrKLASSEN is null) 重新格式化某些数据后,我可以在调试器中看到数据的格式正确(RELATEDARTICLE是可选的,因此,为什么attributeOrBEZIEHUNGENOrKLASSEN为null)

调试确认

But the problem is when i try to save the classes back to a file(as seen below) it is still named PRODUKT and not PRODUKT_FIT, all the other changes i have made to the data is saved correctly. 但是问题是当我尝试将这些类保存回文件(如下所示)时,它仍然命名为PRODUKT而不是PRODUKT_FIT,我对数据所做的所有其他更改都正确保存了。 any idea why this is ? 知道为什么会这样吗?

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();
    }
}

Edit So I tried using XSLT with some success, this is my stylesheet right now 编辑所以我尝试使用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>

This works but it adds blank lines below /RELATEDARTICLES> and </PRODUKT_FIT> So I tried adding <xsl:strip-space elements="*"/> but that made it all into one line, so I added omit-xml-declaration="yes" indent="yes" to the xsl:output but this only partly fixed it as now it looks like this: 此方法有效,但它在/RELATEDARTICLES></PRODUKT_FIT>下添加了空行,因此我尝试添加<xsl:strip-space elements="*"/>但是将它们全部合并为一行,因此我添加了omit-xml-declaration="yes" indent="yes"对xsl:output omit-xml-declaration="yes" indent="yes" ,但这只是部分修复了它,因为现在看起来像这样:

xml文件 which doesnt have the format as before, not sure why though? 哪个没有以前的格式,不确定为什么吗?

Use this in your stylesheet 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="*" />

Of course, you can configure the indent-amount according to your needs. 当然,您可以根据需要配置indent-amount

See Apache Xalan for further info. 有关更多信息,请参见Apache Xalan

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM