xml - 使用 Java 将此 xml 文件解析为指定 JSON 的最简单方法是什么?
问题描述
正文和摘要由一系列段落组成,每个段落都可以有内嵌引用。我最担心的是段落中包含的信息。我现在可以将引文留空。还有一件事,每个段落可以属于一个主要部分和多个小节。
我被要求将小节层次结构实现为“subsection1.subsection2.subsection3”,它通过用点分隔小节来说明层次结构。一开始是想用XOM把xml解析成POJO,然后用GSON把它序列化成JSON。有没有更简单的方法可以采取?
XML(有点长)
全文文档的 JSON 模式
{
"paper_id": <str>, # 40-character sha1 of the PDF
"metadata": {
"title": <str>,
"authors": [ # list of author dicts, in order
{
"first": <str>,
"middle": <list of str>,
"last": <str>,
"suffix": <str>,
"affiliation": <dict>,
"email": <str>
},
...
],
"abstract": [ # list of paragraphs in the abstract
{
"text": <str>,
"cite_spans": [ # list of character indices of inline citations
# e.g. citation "[7]" occurs at positions 151-154 in "text"
# linked to bibliography entry BIBREF3
{
"start": 151,
"end": 154,
"text": "[7]",
"ref_id": "BIBREF3"
},
...
],
"ref_spans": <list of dicts similar to cite_spans>, # e.g. inline reference to "Table 1"
"section": "Abstract"
},
...
],
"body_text": [ # list of paragraphs in full body
# paragraph dicts look the same as above
{
"text": <str>,
"cite_spans": [],
"ref_spans": [],
"eq_spans": [],
"section": "Introduction"
},
...
{
...,
"section": "Conclusion"
}
],
"bib_entries": {
"BIBREF0": {
"ref_id": <str>,
"title": <str>,
"authors": <list of dict> # same structure as earlier,
# but without `affiliation` or `email`
"year": <int>,
"venue": <str>,
"volume": <str>,
"issn": <str>,
"pages": <str>,
"other_ids": {
"DOI": [
<str>
]
}
},
"BIBREF1": {},
...
"BIBREF25": {}
},
"ref_entries":
"FIGREF0": {
"text": <str>, # figure caption text
"type": "figure"
},
...
"TABREF13": {
"text": <str>, # table caption text
"type": "table"
}
},
"back_matter": <list of dict> # same structure as body_text
}
}
解决方案
“最简单”在很大程度上取决于您的技能。
我会使用 XSLT 3.0 来完成。在 XSLT 3.0 中有几种方法可以处理任务;我想我会用构造映射和数组的模板规则来做,然后使用 JSON 序列化方法将映射和数组的结果结构转换为 JSON。以下是您可能使用的两个模板规则,作为示例:
<xsl:output method="json" indent="yes"/>
<xsl:template match="tei:biblStruct/tei:analytic">
<xsl:map:entry key="'authors'" select="f:array-from(tei:author)"/>
</xsl:template>
<xsl:template match="tei:author">
<xsl:map>
<xsl:if test="tei:persName/tei:firstName">
<xsl:map:entry key="'first'" select="string(tei:persName/tei:firstName)"/>
</xsl:if>
<xsl:if test="tei:persName/tei:lastName">
<xsl:map:entry key="'last'" select="string(tei:persName/tei:lastName)"/>
</xsl:if>
...
</xsl:template>
不幸的是,缺少xsl:array
构造数组的指令。如果您使用 Saxon-PE 或更高版本,您可以使用saxon:array
扩展指令来填补这一空白,但您也可以通过编写自己的函数来解决限制,如下所示(您只需执行一次):
<xsl:function name="f:array-from" as="array(*)">
<xsl:param name="elements" select="element(*)*"/>
<xsl:variable name="out" as="item()*">
<xsl:apply-templates select="$elements"/>
</xsl:variable>
<xsl:sequence select="array{$out}"/>
</xsl:function>
推荐阅读
- selenium - Selenium 如何将带有选项的 WebDriver 传递给其他函数 [Kotlin]
- powershell - PowerShell - ScriptBlock 到可迭代类型
- flutter - 从列中删除空间
- python - 如何通过 PyQt5 中的变量添加颜色、背景颜色值?
- java - 如何使用 jtable 中的布尔值来使进度条工作?
- algorithm - 我无法解决与主功率模 1e9+7 相关的问题。我认为要解决这个问题,我们必须使用构造算法
- java - 错误:EmailException (Java):将电子邮件发送到以下服务器失败:smtp.gmail.com:465
- c# - 我可以在 .NET Core 中降低库的日志级别吗?
- javascript - 无法从函数访问 React Reducer 值
- google-cloud-run - 已使用授权标头时在 Google Cloud Run 中测试 OAuth 应用程序