RDF (Resource Description Framework) 為 W3C 標準,核心是「主語-謂語-賓語」三元組,構建語義網元資料模型。Atom 為聚合格式(源自 RSS 限制),以 XML 表達,廣泛用於部落格/社群摘要。Atom 缺乏語義定義,轉為 RDF 可兼具聚合與語義優勢,利於語義網搜尋引擎收錄,提升曝光與流量。
採用 RDF Site Syndication (RSS 1.0) 規範,搭配 Dublin Core Metadata Initiative (DCMI) 補足日期等缺失定義。
// Channel.java:對應 <channel> 區段
public class Channel {
private String about, title, description, link, date;
private List<String> items = new ArrayList<>();
// getter/setter 略
}
// Item.java:對應每個 <item> 區段
public class Item {
private String format, date, link, creator, title, description, source;
// getter/setter 略
}
public class AtomToRdf {
private Channel channel = new Channel();
private List<Item> itemList = new ArrayList<>();
public static void main(String[] args) { new AtomToRdf().go(); }
private void go() { parseAtom(); createRdf(); }
// 常數定義名稱空間
private static final String DUBLIN_CORE_PREFIX = "dc";
private static final String DUBLIN_CORE_URI = "https://purl.org/dc/elements/1.1/";
private static final String RDF_PREFIX = "rdf";
private static final String RDF_URI = "https://www.w3.org/1999/02/22-rdf-syntax-ns#";
private static final String RSS_URI = "https://purl.org/rss/1.0/";
...
}
使用 XMLInputFactory 建立 XMLEventReader,逐事件處理。關鍵邏輯:
boolean inEntry 區分 <feed> 層級的 <title> 與 <entry> 內的 <title>。Item currentItem 暫存單一條目資料,遇 <entry> 起始建立新實例,遇結束加入 itemList。title、content、id、published、link、author 等)提取文字內容,填入 channel 或 currentItem 對應屬性。private void parseAtom() {
try {
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream in = new URL("https://twitter.com/statuses/public_timeline.atom").openStream();
XMLEventReader reader = factory.createXMLEventReader(in);
boolean inEntry = false;
Item currentItem = null;
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
if (event.isStartElement()) {
StartElement elem = event.asStartElement();
String name = elem.getName().getLocalPart();
if ("entry".equals(name)) { inEntry = true; currentItem = new Item(); continue; }
if ("title".equals(name)) {
event = reader.nextEvent();
String val = event.asCharacters().getData();
if (!inEntry) channel.setTitle(val); else currentItem.setTitle(val);
continue;
}
// ... 處理 content, id, published, link, author 等元素 ...
if ("/entry".equals(name)) { // 實際為 EndElement 判斷
itemList.add(currentItem);
inEntry = false;
}
}
}
} catch (Exception e) { e.printStackTrace(); }
}
使用 XMLOutputFactory 建立 XMLStreamWriter,輸出至 c:/twitter.rdf:
<rdf:RDF> 及三個名稱空間(rdf、rss、dc)。writeChannel() 輸出 <channel> 區段(含 <items>/<rdf:Seq> 列出所有項目連結)。writeItems() 迴圈輸出每個 <item> 區段,含 DCMI 元資料(format、date、source、creator)與標準元素(title、link、description)。private void createRdf() {
try {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream("c:/twitter.rdf"));
writer.writeStartElement(RDF_PREFIX, "RDF", RDF_URI);
writer.writeNamespace(RDF_PREFIX, RDF_URI);
writer.writeNamespace("", RSS_URI);
writer.writeNamespace(DUBLIN_CORE_PREFIX, DUBLIN_CORE_URI);
writer.writeCharacters("\n ");
writeChannel(writer);
writeItems(writer);
writer.writeCharacters("\n");
writer.writeEndElement();
writer.writeEndDocument();
writer.close();
} catch (Exception e) { e.printStackTrace(); }
}
AtomToRdf,產生 twitter.rdf。https://www.w3.org/RDF/Validator) 貼上內容驗證,顯示 Your RDF document validated successfully.語義網成主流趨勢,發布相容 RDF 文件至關透。RDF Site Syndication 兼具聚合與語義雙重效益。Java + StAX 輕鬆實現 Atom→RDF 轉換,為站點提供語義化聚合輸出。
本文隨附完整原始碼下載 (AtomToRdf.zip)。