Разбор XML-файла, переименование тега и сохранение его снова - PullRequest
0 голосов
/ 10 декабря 2018

У меня довольно большой 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, BEZIEHUNGSTYP и PRODUKT_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 является необязательным, поэтому атрибутOrBEZIEHUNGENOrKLASSEN имеет значение null)

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, который не имеет формат, как раньше, хотя не уверен почему?

1 Ответ

0 голосов
/ 11 декабря 2018

Используйте это в своем файле таблицы стилей:

    <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 длядальнейшая информация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...