[英]XML to JSON Conversion in R
我已經嘗試了帶有XML包的library(rjson)
。 首先,我解析XML,並使用XML::xmlToList()
將其轉換為列表,然后使用rjson包中的toJSON()
將其轉換為JSON。
我的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
我的源代碼:
rm(list = ls())
library(XML)
library(rjson)
xml_parse<-xmlParse(file = "path/book")
xml_root <- xmlRoot(xml_parse)
xml_list <- xmlToList(xml_root,addAttributes = T, simplify = F)
#rjson package
xml_rjson <-toJSON(xml_list)
cat(xml_rjson)
從rjson轉換的JSON文件:
{
"book": {
"title": {
"text": "Everyday Italian",
".attrs": {
"lang": "en"
}
},
"author": "Giada De Laurentiis",
"year": "2005",
"price": "30.00",
".attrs": {
"category": "cooking"
}
},
"book": {
"title": {
"text": "Harry Potter",
".attrs": {
"lang": "en"
}
},
"author": "J K. Rowling",
"year": "2005",
"price": "29.99",
".attrs": {
"category": "children"
}
},
"book": {
"title": {
"text": "Learning XML",
".attrs": {
"lang": "en"
}
},
"author": "Erik T. Ray",
"year": "2003",
"price": "39.95",
".attrs": {
"category": "web"
}
}
}
這顯然是錯誤的,因為重復的鍵“ book”而沒有根名“ bookstore”。
理想的JSON文件將是這樣的:
{
"bookstore": {
"book": [
{
"-category": "cooking",
"title": {
"-lang": "en",
"#text": "Everyday Italian"
},
"author": "Giada De Laurentiis",
"year": "2005",
"price": "30.00"
},
{
"-category": "children",
"title": {
"-lang": "en",
"#text": "Harry Potter"
},
"author": "J K. Rowling",
"year": "2005",
"price": "29.99"
},
{
"-category": "web",
"title": {
"-lang": "en",
"#text": "Learning XML"
},
"author": "Erik T. Ray",
"year": "2003",
"price": "39.95"
}
]
}
}
期待解決方案。 任何幫助表示贊賞。
正如邁克爾所說,這不是一個好主意。 但是,我們不太可能說服您,因為沒有自動轉換意味着要進行工作以確保一致性和完全可重復性。
由於您似乎喜歡該網站,所以我很確定它使用xml-js
或與之非常接近的東西,因此我整理了一個小的V8包裝器包: https : //github.com/hrbrmstr/blackmagic
xml_to_json()
函數有大量潛在的參數設置,因此請在任何“但它不會自動為我執行xyz”注釋之前進行介紹。
devtools::install_github("hrbrmstr/blackmagic")
'<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>' -> books
cat(xml_to_json(books, spaces = 2, compact = TRUE, ignoreDeclaration = TRUE))
## {
## "bookstore": {
## "book": [
## {
## "_attributes": {
## "category": "cooking"
## },
## "title": {
## "_attributes": {
## "lang": "en"
## },
## "_text": "Everyday Italian"
## },
## "author": {
## "_text": "Giada De Laurentiis"
## },
## "year": {
## "_text": "2005"
## },
## "price": {
## "_text": "30.00"
## }
## },
## {
## "_attributes": {
## "category": "children"
## },
## "title": {
## "_attributes": {
## "lang": "en"
## },
## "_text": "Harry Potter"
## },
## "author": {
## "_text": "J K. Rowling"
## },
## "year": {
## "_text": "2005"
## },
## "price": {
## "_text": "29.99"
## }
## },
## {
## "_attributes": {
## "category": "web"
## },
## "title": {
## "_attributes": {
## "lang": "en"
## },
## "_text": "Learning XML"
## },
## "author": {
## "_text": "Erik T. Ray"
## },
## "year": {
## "_text": "2003"
## },
## "price": {
## "_text": "39.95"
## }
## }
## ]
## }
## }
第一點:沒有將XML轉換為JSON或反之亦然的明確的“正確”方法。 有許多不同的庫可以執行此操作,並且它們的執行方法也有所不同。 不幸的是,選擇了一個實際上會生成不正確的JSON的代碼。
第二點:如果您知道開始使用的是XML以及想要結束使用的JSON,那么您不太可能會找到可以進行所需轉換的庫。
因此,您將不得不進行一些手動調整。 您可以潛在地在轉換之前對輸入進行預處理,或在轉換之后對輸出進行后處理,或者可以“手動”完成全部操作。
在XSLT中(或可能在R中)手工完成整個過程實際上並不那么困難,但是我對此並不熟悉。
我個人的選擇是使用XSLT 3.0將XML轉換為映射和數組,然后將結果序列化為JSON:
<xsl:output method="json" indent="yes">
<xsl:template match="booklist">
<xsl:map-entry key="'booklist'">
<xsl:map-entry key="'book'">
<saxon:array>
<xsl:for-each select="book">
<saxon:array-member>
<xsl:map>
<xsl:map-entry key="'-category'" select="@category"/>
<xsl:map-entry key="'title'">
<xsl:apply-templates select="title"/>
</xsl:map-entry>
<xsl:map-entry key="'author'" select="author"/>
<xsl:map-entry key="'year'" select="year"/>
<xsl:map-entry key="'price'" select="price"/>
</xsl:map>
</saxon:array-member>
</xsl:for-each>
</saxon:array>
</xsl:map-entry>
</xsl:map-entry>
</xsl:template>
<xsl:template match="title">
<xsl:map-entry key="'-lang'" select="@lang"/>
<xsl:map-entry key="'#text'" select="string(.)"/>
</xsl:template>
當然,您也可以嘗試概括其中一些規則,例如使模板規則匹配所有屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.