json - xml到json中单个和多个LineItem的方括号
问题描述
如何为单个或多个“详细信息”行项获取方括号或数组。需要获得方括号或数组 [ 即使对于单行“详细信息”也是如此。我们有超过 1 行“详细信息”。要求是填充 [ 甚至从单行“详细信息”。
单行“详细信息”的 xmlFile:
<root>
<FirstName>Alex</FirstName>
<LastName>Fin</LastName>
<Details>
<Id_Number>111</Id_Number>
<Location>NC</Location>
<Contact>
<PhoneNumber>+1 323</PhoneNumber>
</Contact>
</Details>
</root>
预期的Json文件:
{
"FirstName": "Alex",
"LastName": "Fin",
"Details": [
{
"Id_Number": 111,
"Location": "NC",
"Contact": {
"PhoneNumber": "+1 323"
}
}
]
}
带有多行'详细信息的xml文件:
<root>
<FirstName>Alex</FirstName>
<LastName>Fin</LastName>
<Details>
<Id_Number>111</Id_Number>
<Location>NC</Location>
<Contact>
<PhoneNumber>+1 323</PhoneNumber>
</Contact>
</Details>
<Details>
<Id_Number>222</Id_Number>
<Location>TX</Location>
<Contact>
<PhoneNumber>+1 323</PhoneNumber>
</Contact>
</Details>
<Address>
<Locality>Urban</Locality>
<Distance>
<Miles>2</Miles>
</Distance>
<Commute>Yes</Commute>
</Address>
<Address>
<Locality>Rular</Locality>
<Distance>
<Miles>1</Miles>
</Distance>
<Commute>Yes</Commute>
</Address>
</root>
多个 LineItems'Details' 的预期 Jsonfile
{
"FirstName": "Alex",
"LastName": "Fin",
"Details": [
{
"Id_Number": 111,
"Location": "NC",
"Contact": {
"PhoneNumber": "+1 323"
}
},
{
"Id_Number": 222,
"Location": "TX",
"Contact": {
"PhoneNumber": "+1 323"
}
}
],
"Address": [
[
{
"Locality": "Urban",
"Distance": {
"Miles": 2
},
"Commute": "Yes"
}
],
[
{
"Locality": "Rular",
"Distance": {
"Miles": 1
},
"Commute": "Yes"
}
]
]
}
xslt代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
xmlns="http://www.w3.org/2005/xpath-functions"
expand-text="yes"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="json-xml">
<xsl:apply-templates/>
</xsl:variable>
<xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="*[not(*)]">
<string key="{local-name()}">{.}</string>
</xsl:template>
<xsl:template match="*[(*) and . castable as xs:double]">
<number key="{local-name()}">{.}</number>
</xsl:template>
<xsl:template match="*[*]">
<xsl:param name="key" as="xs:boolean" select="false()"/>
<map>
<xsl:if test="$key">
<xsl:attribute name="key" select="local-name()"/>
</xsl:if>
<xsl:for-each-group select="*" group-by="node-name()">
<xsl:choose>
<xsl:when test="current-group()[2] or self::Details or self::Contact">
<array key="{local-name()}">
<xsl:choose>
<xsl:when test="self::Address">
<array>
<xsl:apply-templates select="current-group()">
<xsl:with-param name="key" select="false()"/>
</xsl:apply-templates>
</array>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()">
<xsl:with-param name="key" select="false()"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</array>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()">
<xsl:with-param name="key" select="true()"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</map>
</xsl:template>
</xsl:stylesheet>
解决方案
当一组同名节点包含两个或多个项目时,代码将生成一个数组:
<xsl:when test="current-group()[2]">
<array key="{local-name()}">
<xsl:apply-templates select="current-group()"/>
</array>
</xsl:when>
所以最简单的解决方法是在元素名称为“详细信息”时使用相同的逻辑:
<xsl:when test="current-group()[2] or self::Details">
或者更好的设计可能是使其成为数据驱动的;有一个全局变量,其中包含要强制数组输出的元素名称列表,并测试该元素在此列表中的成员资格。
推荐阅读
- javascript - Vue:在销毁时删除事件侦听器
- css - 如何降低 Animate.css 的动画强度?
- r - R ggvis:使用 input_select 在 x 轴上设置变量
- google-cloud-platform - 尽管配额增加,但无法使用更多 GPU 启动 gcloud 实例
- php - 中间件“身份验证”说明
- javascript - 在空输入字段 ReactJS 上显示错误
- css - 为什么css没有加载[codeigniter]
- nunjucks - Metalsmith 没有逃脱 Markdown + Nunjucks 的输出
- node.js - 使用 reactjs 作为前端和 nodejs 使用 oracledb 作为后端的登录页面
- animation - SVG 动画在 webpack 加载动态 Vue 组件时暂停