У меня довольно большой 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)
Нопроблема заключается в том, что когда я пытаюсь сохранить классы обратно в файл (как показано ниже), он по-прежнему называется 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, но это только частично исправило это, как теперь это выглядит так:
, который не имеет формат, как раньше, хотя не уверен почему?