如何编写用于将 XML 转换为 JSON 的 XSLT?
How to write XSLT for Converting XML to JSON?
我有以下 XML 文件作为输入,并且想要使用 XSLT 映射的 JSON 输出。如何设计我的 XSLT 文件?
XML 输入:
<?xml version="1.0" encoding="ISO-8859-1"?>
<SyncItemMaster versionID="2.14.0" releaseID="9.2"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.14.0/InforOAGIS/BODs/SyncItemMaster.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schema.infor.com/InforOAGIS/2">
<ApplicationArea>
<Sender>
<LogicalID>lid://infor.ln.ln_1100</LogicalID>
<ComponentID>erp</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2020-06-16T11:00:16Z</CreationDateTime>
<BODID>infor-nid:infor:1100::11064973:?ItemMaster&verb=Sync</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<TenantID>infor</TenantID>
<AccountingEntityID>1100</AccountingEntityID>
<LocationID/>
<ActionCriteria>
<ActionExpression actionCode="Change"/>
</ActionCriteria>
</Sync>
<ItemMaster>
<ItemMasterHeader>
<ItemID>
<ID variationID="4241287" lid="lid://infor.ln.ln_1100" accountingEntity="1100">11064973</ID>
</ItemID>
<DisplayID>11064973</DisplayID>
<GTIN/>
<ServiceIndicator>false</ServiceIndicator>
<Description>H3BO3 4% mit Sher Indikator</Description>
<Description languageID="de_DE">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="fr_FR">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="it_IT">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="nl_NL">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="en_US">H3BO3 4% mit Sher Indikator</Description>
<Note/>
</ItemMasterHeader>
</ItemMaster>
</DataArea>
</SyncItemMaster>
预期JSON输出:
{
"description":[
{
"languageID":"ge_GE",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"de_DE",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"fr_FR",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"it_IT",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"nl_NL",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"en_US",
"text":"H3BO3 4% mit Sher Indikator"
}
]
}
通常,在 XSLT 3 中您有两个选择,创建 JSON 作为相应的 XPath 3.1 映射和数组 (https://xsltfiddle.liberty-development.net/pNmCzsG):
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:template match="/">
<xsl:sequence
select="map {
'description' : array {
//Description !
map {
'languageID' : (data(@languageID), 'ge_GE') => head(),
'text' : data()
}
}
}"/>
</xsl:template>
</xsl:stylesheet>
或将 XML 输入转换为 xml-to-json
函数期望的 XML 输入格式(参见
的中间结果
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
xmlns="http://www.w3.org/2005/xpath-functions"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<map>
<xsl:where-populated>
<array key="description">
<xsl:apply-templates select="//Description"/>
</array>
</xsl:where-populated>
</map>
</xsl:template>
<xsl:template match="Description[not(@languageID)]">
<map>
<string key="languageID">ge_GE</string>
<string key="text">{.}</string>
</map>
</xsl:template>
<xsl:template match="Description">
<map>
<string key="languageID">{@languageID}</string>
<string key="text">{.}</string>
</map>
</xsl:template>
</xsl:stylesheet>
) 然后使用该函数 xml-to-json
(https://xsltfiddle.liberty-development.net/pNmCzsG/1):
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
xmlns="http://www.w3.org/2005/xpath-functions"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="json-xml">
<map>
<xsl:where-populated>
<array key="description">
<xsl:apply-templates select="//Description"/>
</array>
</xsl:where-populated>
</map>
</xsl:variable>
<xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="Description[not(@languageID)]">
<map>
<string key="languageID">ge_GE</string>
<string key="text">{.}</string>
</map>
</xsl:template>
<xsl:template match="Description">
<map>
<string key="languageID">{@languageID}</string>
<string key="text">{.}</string>
</map>
</xsl:template>
</xsl:stylesheet>
上面显示的第一次尝试没有定义 JSON 属性 输出的顺序,除非您使用 Saxon 特定的扩展属性。根据第二个建议,您可以定义顺序。
我有以下 XML 文件作为输入,并且想要使用 XSLT 映射的 JSON 输出。如何设计我的 XSLT 文件?
XML 输入:
<?xml version="1.0" encoding="ISO-8859-1"?>
<SyncItemMaster versionID="2.14.0" releaseID="9.2"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.14.0/InforOAGIS/BODs/SyncItemMaster.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schema.infor.com/InforOAGIS/2">
<ApplicationArea>
<Sender>
<LogicalID>lid://infor.ln.ln_1100</LogicalID>
<ComponentID>erp</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2020-06-16T11:00:16Z</CreationDateTime>
<BODID>infor-nid:infor:1100::11064973:?ItemMaster&verb=Sync</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<TenantID>infor</TenantID>
<AccountingEntityID>1100</AccountingEntityID>
<LocationID/>
<ActionCriteria>
<ActionExpression actionCode="Change"/>
</ActionCriteria>
</Sync>
<ItemMaster>
<ItemMasterHeader>
<ItemID>
<ID variationID="4241287" lid="lid://infor.ln.ln_1100" accountingEntity="1100">11064973</ID>
</ItemID>
<DisplayID>11064973</DisplayID>
<GTIN/>
<ServiceIndicator>false</ServiceIndicator>
<Description>H3BO3 4% mit Sher Indikator</Description>
<Description languageID="de_DE">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="fr_FR">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="it_IT">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="nl_NL">H3BO3 4% mit Sher Indikator</Description>
<Description languageID="en_US">H3BO3 4% mit Sher Indikator</Description>
<Note/>
</ItemMasterHeader>
</ItemMaster>
</DataArea>
</SyncItemMaster>
预期JSON输出:
{
"description":[
{
"languageID":"ge_GE",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"de_DE",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"fr_FR",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"it_IT",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"nl_NL",
"text":"H3BO3 4% mit Sher Indikator"
},
{
"languageID":"en_US",
"text":"H3BO3 4% mit Sher Indikator"
}
]
}
通常,在 XSLT 3 中您有两个选择,创建 JSON 作为相应的 XPath 3.1 映射和数组 (https://xsltfiddle.liberty-development.net/pNmCzsG):
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:template match="/">
<xsl:sequence
select="map {
'description' : array {
//Description !
map {
'languageID' : (data(@languageID), 'ge_GE') => head(),
'text' : data()
}
}
}"/>
</xsl:template>
</xsl:stylesheet>
或将 XML 输入转换为 xml-to-json
函数期望的 XML 输入格式(参见
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
xmlns="http://www.w3.org/2005/xpath-functions"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<map>
<xsl:where-populated>
<array key="description">
<xsl:apply-templates select="//Description"/>
</array>
</xsl:where-populated>
</map>
</xsl:template>
<xsl:template match="Description[not(@languageID)]">
<map>
<string key="languageID">ge_GE</string>
<string key="text">{.}</string>
</map>
</xsl:template>
<xsl:template match="Description">
<map>
<string key="languageID">{@languageID}</string>
<string key="text">{.}</string>
</map>
</xsl:template>
</xsl:stylesheet>
) 然后使用该函数 xml-to-json
(https://xsltfiddle.liberty-development.net/pNmCzsG/1):
<?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"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2"
xmlns="http://www.w3.org/2005/xpath-functions"
expand-text="yes"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:variable name="json-xml">
<map>
<xsl:where-populated>
<array key="description">
<xsl:apply-templates select="//Description"/>
</array>
</xsl:where-populated>
</map>
</xsl:variable>
<xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="Description[not(@languageID)]">
<map>
<string key="languageID">ge_GE</string>
<string key="text">{.}</string>
</map>
</xsl:template>
<xsl:template match="Description">
<map>
<string key="languageID">{@languageID}</string>
<string key="text">{.}</string>
</map>
</xsl:template>
</xsl:stylesheet>
上面显示的第一次尝试没有定义 JSON 属性 输出的顺序,除非您使用 Saxon 特定的扩展属性。根据第二个建议,您可以定义顺序。