0

I have a pretty big xml file and need to change some of it, this is a snippet of how it looks

<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.

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:

<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,BEZIEHUNGSTYPand PRODUKT_FIT and I changed the definition for the class PRDUKT as seen here

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.

The PRODUKT_FIT class is shown below:

@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)

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)

debugging confirmation

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. 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

<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:

xml file which doesnt have the format as before, not sure why though?

2
  • 1
    See Java XSLT Commented Dec 10, 2018 at 18:31
  • I made an edit to my post, thx for the link though! Commented Dec 11, 2018 at 10:00

1 Answer 1

1

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.

See Apache Xalan for further info.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.