使用XSLT转换嵌套JSON为XML时的StudentAddress节点问题咨询
问题
使用XSLT的json-to-xml函数转换JSON到XML时,其他节点正常,但StudentAddress下的嵌套子JSON(PermanentAddress和CurrentAddress)转换异常,仅能获取HomeTowndistrict和PinCode的内容,需修改XSLT以正确转换永久地址和当前地址的详细信息。
原始JSON数据
{"envelope": {"header": {"AddmisionId": "1"},"body": {"StudentRequest": {"StudentDetails": {"FirstName": "AMIT","Telephone": "1234567890","RollNo": "1"},"StudentAddress": {"HomeTowndistrict": "BLR","PermanentAddress": {"addressLine2": "BLR","addressLine3": "PQR","addressLine5": "WH"},"CurrentAddress": {"addressLine2": "GYA","addressLine3": "MNO","addressLine5": "QW"},"PinCode": "5600"},"MarkList": {"marks": [{"name": "math","id": "math80"},{"name": "science","id": "science123"},{"name": "English","id": ""},{"name": "Sport","id": "S23"}]},"Report": {"STD": "1","Code": "QRT90"}}}}}
预期输出XML
<CLG:StudentRequest xmlns:ns0="http://www.w3.org/2005/xpath-functions"><CLG:StudentAddress><CLG:HomeTowndistrict>BLR</CLG:HomeTowndistrict><CLG:PermanentAddress><ssp:addressLine1/><ssp:addressLine2>BLR</ssp:addressLine2><ssp:addressLine3>PQR</ssp:addressLine3><ssp:addressLine4/><ssp:addressLine5/><ssp:addressLine5>WH</ssp:addressLine5></CLG:PermanentAddress><CLG:CurrentAddress><ssp:addressLine1/><ssp:addressLine2>GYA</ssp:addressLine2><ssp:addressLine3>MNO</ssp:addressLine3><ssp:addressLine4/><ssp:addressLine5>QW</ssp:addressLine5></CLG:CurrentAddress><CLG:PinCode>5600</CLG:PinCode><CLG:studentUser><CLG:studentUser/></CLG:studentUser></CLG:StudentAddress><CLG:Report><CLG:STD>1</CLG:STD><CLG:Code>QRT90</CLG:Code></CLG:Report><CLG:MarkList><CLG:marks><CLG:name>math</CLG:name><CLG:id>math80</CLG:id></CLG:marks><CLG:marks><CLG:name>science</CLG:name><CLG:id>science123</CLG:id></CLG:marks><CLG:marks><CLG:name>English</CLG:name><CLG:id/></CLG:marks><CLG:marks><CLG:name>Sport</CLG:name><CLG:id>S23</CLG:id></CLG:marks></CLG:MarkList><CLG:StudentDetails><FirstName>AMIT</FirstName><Telephone>1234567890</Telephone><RollNo>1</RollNo></CLG:StudentDetails></CLG:StudentRequest>
当前使用的XSLT
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:CLG="http://www.w3.org/2005/xpath-functions" xmlns:ns0="http://www.w3.org/2005/xpath-functions" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ssp="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn" expand-text="yes"><xsl:strip-space elements="*" /><xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /><xsl:param name="jsonText" /><xsl:template name="init"><CLG:StudentRequest xmlns="##namespace##"><xsl:apply-templates select="json-to-xml($jsonText)" /></CLG:StudentRequest></xsl:template><xsl:template match="fn:map[@key = 'Report']"><CLG:Report><CLG:STD>{fn:string[@key = 'STD']}</CLG:STD><CLG:Code>{fn:string[@key = 'Code']}</CLG:Code></CLG:Report></xsl:template><xsl:template match="fn:array[@key = 'marks']"><CLG:MarkList><xsl:iterate select="*"><CLG:marks><CLG:name>{fn:string[@key = 'name']}</CLG:name><CLG:id>{fn:string[@key = 'id']}</CLG:id></CLG:marks></xsl:iterate></CLG:MarkList></xsl:template><xsl:template match="fn:map[@key = 'StudentAddress']"><CLG:StudentAddress><CLG:PermanentAddress><ssp:addressLine1>{fn:string[@key = 'addressLine1']}</ssp:addressLine1><ssp:addressLine2>{fn:string[@key = 'addressLine2']}</ssp:addressLine2><ssp:addressLine3>{fn:string[@key = 'addressLine3']}</ssp:addressLine3><ssp:addressLine4>{fn:string[@key = 'addressLine4']}</ssp:addressLine4><ssp:addressLine5>{fn:string[@key = 'addressLine5']}</ssp:addressLine5></CLG:PermanentAddress><CLG:CurrentAddress><ssp:addressLine1>{fn:string[@key = 'addressLine1']}</ssp:addressLine1><ssp:addressLine2>{fn:string[@key = 'addressLine2']}</ssp:addressLine2><ssp:addressLine3>{fn:string[@key = 'addressLine3']}</ssp:addressLine3><ssp:addressLine4>{fn:string[@key = 'addressLine4']}</ssp:addressLine4><ssp:addressLine5>{fn:string[@key = 'addressLine5']}</ssp:addressLine5></CLG:CurrentAddress><CLG:HomeTowndistrict>{fn:string[@key = 'StudentAddress']}</CLG:HomeTowndistrict><CLG:PinCode>{fn:string[@key = 'PinCode']}</CLG:PinCode><CLG:studentUser><CLG:studentUser>{fn:string[@key = 'studentUser']}</CLG:studentUser></CLG:studentUser></CLG:StudentAddress></xsl:template><xsl:template match="fn:map[@key = 'StudentDetails']"><CLG:StudentDetails><FirstName>{fn:string[@key = 'FirstName']}</FirstName><Telephone>{fn:string[@key = 'Telephone']}</Telephone><RollNo>{fn:string[@key = 'RollNo']}</RollNo></CLG:StudentDetails></xsl:template></xsl:stylesheet>
解决方案
问题出在StudentAddress的匹配模板中:直接从当前fn:map节点下获取addressLine*节点是错误的,因为PermanentAddress和CurrentAddress本身是嵌套的fn:map节点,需要先定位到对应的子map,再提取内部数据;同时HomeTowndistrict的取值路径也存在错误。
具体修改点
- 修正
HomeTowndistrict的取值路径:将{fn:string[@key = 'StudentAddress']}改为{fn:string[@key = 'HomeTowndistrict']} - 定位嵌套子map:通过
fn:map[@key='PermanentAddress']和fn:map[@key='CurrentAddress']找到对应的子节点,再从中提取地址行数据 - 空标签处理:对于JSON中不存在的
addressLine1、addressLine4,直接输出空标签以匹配预期结构
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:CLG="http://www.w3.org/2005/xpath-functions" xmlns:ns0="http://www.w3.org/2005/xpath-functions" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ssp="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn" expand-text="yes"> <xsl:strip-space elements="*" /> <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" /> <xsl:param name="jsonText" /> <xsl:template name="init"> <CLG:StudentRequest xmlns="##namespace##"> <xsl:apply-templates select="json-to-xml($jsonText)" /> </CLG:StudentRequest> </xsl:template> <xsl:template match="fn:map[@key = 'Report']"> <CLG:Report> <CLG:STD>{fn:string[@key = 'STD']}</CLG:STD> <CLG:Code>{fn:string[@key = 'Code']}</CLG:Code> </CLG:Report> </xsl:template> <xsl:template match="fn:array[@key = 'marks']"> <CLG:MarkList> <xsl:iterate select="*"> <CLG:marks> <CLG:name>{fn:string[@key = 'name']}</CLG:name> <CLG:id>{fn:string[@key = 'id']}</CLG:id> </CLG:marks> </xsl:iterate> </CLG:MarkList> </xsl:template> <xsl:template match="fn:map[@key = 'StudentAddress']"> <CLG:StudentAddress> <CLG:HomeTowndistrict>{fn:string[@key = 'HomeTowndistrict']}</CLG:HomeTowndistrict> <CLG:PermanentAddress> <ssp:addressLine1/> <ssp:addressLine2>{fn:map[@key='PermanentAddress']/fn:string[@key='addressLine2']}</ssp:addressLine2> <ssp:addressLine3>{fn:map[@key='PermanentAddress']/fn:string[@key='addressLine3']}</ssp:addressLine3> <ssp:addressLine4/> <ssp:addressLine5>{fn:map[@key='PermanentAddress']/fn:string[@key='addressLine5']}</ssp:addressLine5> </CLG:PermanentAddress> <CLG:CurrentAddress> <ssp:addressLine1/> <ssp:addressLine2>{fn:map[@key='CurrentAddress']/fn:string[@key='addressLine2']}</ssp:addressLine2> <ssp:addressLine3>{fn:map[@key='CurrentAddress']/fn:string[@key='addressLine3']}</ssp:addressLine3> <ssp:addressLine4/> <ssp:addressLine5>{fn:map[@key='CurrentAddress']/fn:string[@key='addressLine5']}</ssp:addressLine5> </CLG:CurrentAddress> <CLG:PinCode>{fn:string[@key = 'PinCode']}</CLG:PinCode> <CLG:studentUser> <CLG:studentUser/> </CLG:studentUser> </CLG:StudentAddress> </xsl:template> <xsl:template match="fn:map[@key = 'StudentDetails']"> <CLG:StudentDetails> <FirstName>{fn:string[@key = 'FirstName']}</FirstName> <Telephone>{fn:string[@key = 'Telephone']}</Telephone> <RollNo>{fn:string[@key = 'RollNo']}</RollNo> </CLG:StudentDetails> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者AmitKr
相关产品推荐
相关产品推荐

