注:我是EclipseLink JAXB (MOXy)鉛和JAXB (JSR-222)專家組
的成員,以下是你可以處理這個用例有兩種方式。第一個是更多的代碼,但可以通過任何JAXB實現來完成。第二個代碼較少,但需要使用EclipseLink JAXB(MOXy)。
選項1 - 任何JAXB(JSR-222)實現
演示
你可以使用一個過濾的流閱讀器來過濾掉不需要的元素,讓你的JAXB實現解組那。
package forum11586106;
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
private static final String LANGUAGE_CODE = "en";
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/forum11586106/input.xml"));
xsr = xif.createFilteredReader(xsr, new StreamFilter() {
private boolean isReading = true;
@Override
public boolean accept(XMLStreamReader reader) {
if(reader.isStartElement() && "Name".equals(reader.getLocalName())) {
isReading = LANGUAGE_CODE.equals(reader.getAttributeValue("", "language"));
return isReading;
} else if(reader.isEndElement() && !isReading) {
isReading = true;
return false;
}
return true;
}});
JAXBContext jc = JAXBContext.newInstance(Countries.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Countries countries = (Countries) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(countries, System.out);
}
}
國家
package forum11586106;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Countries {
private String name;
@XmlElement(name="Name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
的input.xml
這種方法的語言屬性不包含在輸出:
<countries>
<Name language="en">Australia</Name>
<Name language="se">Australien</Name>
</countries>
輸出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<countries>
<Name>Australia</Name>
</countries>
選項#2 - 的EclipseLink JAXB(莫西)
我們將利用莫西的@XmlPath
擴展映射到具有language
的Name
元素屬性值爲en
(請參閱http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html)。
國家
package forum11586106;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement
public class Countries {
private String name;
@XmlPath("Name[@language='en']/text()")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
jaxb.properties
要使用莫西爲您的JAXB提供你需要包括一個文件在同一個包爲您的域模型稱爲jaxb.properties
與以下條目(請參閱:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
演示
這種方法的元件的過濾是由@XmlPath
映射處理,因此運行時部分變得簡單得多。注意只使用標準的JAXB運行時API。
package forum11586106;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Countries.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11586106/input.xml");
Countries countries = (Countries) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(countries, System.out);
}
}
input.xml中
<countries>
<Name language="en">Australia</Name>
<Name language="se">Australien</Name>
</countries>
輸出
這種方法的language
屬性被包括在輸出:
<?xml version="1.0" encoding="UTF-8"?>
<countries>
<Name language="en">Australia</Name>
</countries>
謝謝!第一個版本完美運行。我通常不使用Eclipse,但我嘗試過,但無法讓MOXy版本正常工作。 – Patrik 2012-07-26 06:53:09
@PatrikNilsson - 您需要確保您使用的是EclipseLink 2.3或更高版本(當前版本爲EclipseLink 2.4)。您可以從以下網址下載獨立版本的EclipseLink:http://www.eclipse.org/eclipselink/downloads/ – 2012-07-26 15:23:37