我正在更新一个使用 JAXB 1.0 和内部编写的 MusicXML 1.0 模式的 Java 应用程序,以使用 JAXB 2.2 和供应商提供的 MusicXML 3.0 模式。当我使用 JAXB 2.2 为 <part-list> 解组具有多个 <score-part> 子元素的文件时,仅返回 1 个 <score-part> 元素。我目前正在使用 DOM 的解决方法来获取附加的 <score-parts> 但这并不是很理想,因为我要解析文件两次以获取数据。如何让 JAXB 返回 <part-list> 中的所有 <score-parts>?
<part-list> 的 MusicXML 1.0 架构片段
<xs:element name="part-list">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="part-group"/>
<xs:element ref="score-part"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="part-group"/>
<xs:element ref="score-part"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<part-list> 的 MusicXML 3.0 架构片段
<xs:complexType name="part-list">
<xs:sequence>
<xs:group ref="part-group" minOccurs="0" maxOccurs="unbounded"/>
<xs:group ref="score-part"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="part-group"/>
<xs:group ref="score-part"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
用于解组的 Java 片段
package test;
import java.io.FileInputStream;
import java.util.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import recodare.MusicXML.*;
import javax.xml.bind.JAXBElement;
public class MusicXMLReader{
private java.lang.String m_sXMLFielPath = "";
private ScorePartwise m_spScorePartwise = null;
public MusicXMLReader(java.lang.String filePath){
m_sXMLFilePath = filePath;
}
public void processXML() throws Exception{
JAXBContext jc = JAXBContext.newInstance("recodare.MusicXML");
Unmarshaller u = jc.createUnmarshaller();
m_spScorePartwise = (ScorePartwise)u.unmarshal(new FileInputStream(m_sXMLFilePath));
PartList pl = m_spScorePartwise.getPartList();
ScorePart scorePart = pl.getScorePart(); // 1st score-part
// for remaining score-part or part-group this list is null even when part-list
// has multiple score-part elements
List<Object> listPartGroupOrScorePart = pl.getPartGroupOrScorePart();
//continue processing file
}
}
对于测试数据,我使用来自The Unofficial MusicXML Test Suite 的文件 41a-MultiParts-Partorder.xml 和 41b-MultiParts-MoreThan10.xml
如果您希望为 MusicXML 3.0 构建 JAXB 绑定,您可能会从 JAXB 收到以下(或类似)错误
[ERROR] Property "Segno" is already defined. Use <jaxb:property> to resolve this conflict.
line 2793 of file: musicxml.xsd
[ERROR] The following location is relevant to the above error
line 2800 file: musicXML.xsd
[ERROR] Property "Coda" is already defined. Use <jaxb:property> to resolve this conflict.
line 2794 of musicXML.xsd
[ERROR] The following location is relevant to the above error
line 2801 of file: musicXML.xsd
[ERROR] Element "link" shows up in more than one properties.
line 4765 of file: musicXML.xsd
[ERROR] Element "bookmark" shows up in more than one properties.
line 4766 of file: musicXML.xsd
在这种情况下,请按照此处概述的步骤进行操作