如何从基于属性的xml转换为json,并通过使用XSLT / XSL忽略来自特定元素的属性 [英] how transform from xml based on attributes to json and ignore the attributes from especific elements by using XSLT/XSL
问题描述
我在这里找到了一个很好的答案使用XSLT将XML转换为JSON的问题关于如何从xml移动到json,但是我的xml有点不同。请注意,值是属性的一部分。另外,我想忽略来自c:item的属性。换句话说,鳕鱼和包必须被忽略。我知道如何将这个基于属性的xml转换为基于元素值的另一个xml,然后以json格式转换这个新的xml,但是似乎对我来说有一点奇怪,第一步(从xml到另一个xml),因为我只想要json 。我知道从xml到xml感谢这里提供的优秀答案,而使用XSLT将属性转换为元素如何只忽略父元素中的属性
incoming xml
< c:product xmlns:c =myapp>
< c:item cod =789>
< c:aa name =024value =123/>
< c:bbb name =0105value =123456/>
< c:bbb name =0122value =T/>
< c:aa name =071value =00000001/>
< / c:item>
< c:item package =123cod =11111>
< c:aa name =002value =753/>
< c:aa name =003value =456/>
< c:bbb name =0146value =147852/>
< / c:item>
< / c:product>
输出xml只是为了举例说明我目前使用的额外步骤,即如果我我有义务从xml到xml的额外步骤,只是从c:item中取出属性,并将值作为元素而不是属性形成,然后从xml到json
<产品>
< item>
< aa>
< name> 024< / name>
< value> 123< / value>
< / aa>
< bbb>
< name> 0105< / name>
< value> 123456< / value>
< / bbb>
< bbb>
< name> 0122< / name>
< value> T< / value>
< / bbb>
< aa>
< name> 071< / name>
< value> 00000001< / value>
< / aa>
< / item>
< item>
< aa>
< name> 002< / name>
< value> 753< / value>
< / aa>
< aa>
< name> 003< / name>
< value> 456< / value>
< / aa>
< bbb>
< name> 0146< / name>
< value> 147852< / value>
< / bbb>
< / item>
< / product>
用于从xml转换为xml的当前xls
< xsl:stylesheet version =1.0
xmlns:xsl =http://www.w3.org/1999/XSL/Transform
xmlns:c =myapp
exclude-result-prefixes =c>
< xsl:output method =xmlomit-xml-declaration =yesversion =1.0encoding =utf-8indent =yes/>
< xsl:strip-space elements =*/>
< xsl:template match =*>
< xsl:element name ={local-name()}>
< xsl:apply-templates select =@ * | node()/>
< / xsl:element>
< / xsl:template>
< xsl:template match =c:item>
< xsl:element name ={local-name()}>
< xsl:apply-templates />
< / xsl:element>
< / xsl:template>
< xsl:template match =@ *>
< xsl:element name ={local-name()}>
< xsl:value-of select =。/>
< / xsl:element>
< / xsl:template>
< / xsl:stylesheet>
结果和所需的json(很好,只是想象一下在json文件中转换的最后一个xml)
{
{
aa:{024:123}
bbb :{0105,123456}
bbb:{0122,T}
aa:{071,00000001}
}
{
{
...
}
}
****编辑7月31日
输出基于Michael Kay答案:
aa:{024:123}bbb:{0105:123456}bbb:{0122:T :{071:00000001}aa:{002:753}aa:{003:456}bbb:{0146:147852}
基于Michael Kay回答并产生以上结果使用的XLS
< xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transformxmlns:c =myapp exclude-result-prefixes =c>
< xsl:output method =xmlomit-xml-declaration =yesversion =1.0encoding =utf-8indent =yes/>
< xsl:strip-space elements =*/>
< xsl:template match =c:item / *>
< xsl:text>< / xsl:text>
< xsl:value-of select =local-name()/>
< xsl:text> ; :{< / xsl:text>
< xsl:value-of select =@ name/>
< xsl:text>:< / xsl:text>
< xsl:value-of select =@ value/>
< xsl:text>}< / xsl:text>
< / xsl:template>
< / xsl:stylesheet>
您所展示的XSLT是在正确的路径上,但你缺少一些东西
- 没有模板处理
c:item
本身将子节点包裹在{}
- 不输出逗号和换行符来分隔对象
- 没有处理根元素
c:product
来创建一个子数组(所以你有有效的JSON)
尝试这个XSLT
< xsl:stylesheet xmlns:xsl =http: //www.w3.org/1999/XSL/Transformversion =1.0
xmlns:c =myappexclude-result-prefixes =c>
< xsl:output method =text/>
< xsl:strip-space elements =*/>
< xsl:template match =* [c:item]>
< xsl:text> [&#10;< / xsl:text>
< xsl:apply-templates select =c:item/>
< xsl:text>]&#10;< / xsl:text>
< / xsl:template>
< xsl:template match =c:item>
< xsl:text> {&安培;#10;< / XSL:文本>
< xsl:apply-templates />
< xsl:text> }< / XSL:文本>
< xsl:if test =following-sibling :: c:item>
< xsl:text>,< / xsl:text>
< / xsl:if>
< xsl:text>&#10;< / xsl:text>
< / xsl:template>
< xsl:template match =c:item / *>
< xsl:text> < / xsl:text>
< xsl:value-of select =local-name()/>
< xsl:text> :{< / xsl:text>
< xsl:value-of select =@ name/>
< xsl:text>:< / xsl:text> < xsl:value-of select =@ value/>
< xsl:text>}< / xsl:text>
< xsl:if test =following-sibling :: *>
< xsl:text>,< / xsl:text>
< / xsl:if>
< xsl:text>&#10;< / xsl:text>
< / xsl:template>
< / xsl:stylesheet>
将此XSLT应用于以下XML
< c:product xmlns:c =myapp>
< c:item cod =789>
< c:aa name =024value =123/>
< c:bbb name =0105value =123456/>
< c:bbb name =0122value =T/>
< c:aa name =071value =00000001/>
< / c:item>
< c:item package =123cod =11111>
< c:aa name =002value =753/>
< c:aa name =003value =456/>
< c:bbb name =0146value =147852/>
< / c:item>
< / c:product>
以下是输出
[
{
aa:{024:123},
bbb:{0105:123456},
bbb:{0122:T},
aa:{071:00000001}
},
{
aa:{002:753},
aa:{003:456},
bbb:{0146:147852}
}
]
这不符合您问题中所需的输出,但是您显示的输出实际上不是有效的JSON。
在 http://xsltransform.net/ejivdGD
I believe my question provides a good idea what I am trying to do. BTW, find below the incoming xml and desired json output.
I found an excellent answer here Problems converting XML to JSON using XSLT about how to move from xml to json but my xml is a bit different. Kindly, note below that the values are part of the attributes. Additionally, I want to ignore the attributes from c:item. In other words, cod and package must be ignored. I know how to transform such xml based on attributes to another xml based on element values and then transform this new xml in json format but it seems to me a bit strange the first step (from xml to another xml) since I want the json only. I know from xml to xml thanks to the excellent answer just provided here while transforming attributes to element with XSLT how ignore only the attributes in parent element
incoming xml
<c:product xmlns:c="myapp">
<c:item cod="789">
<c:aa name="024" value="123"/>
<c:bbb name="0105" value="123456"/>
<c:bbb name="0122" value="T"/>
<c:aa name="071" value="00000001"/>
</c:item>
<c:item package="123" cod="11111">
<c:aa name="002" value="753"/>
<c:aa name="003" value="456"/>
<c:bbb name="0146" value="147852"/>
</c:item>
</c:product>
output xml just to exemplify the extra step I have to do with my current knolege, i.e, if I am obligated to do the extra step from xml to xml just to take out the attributes from c:item and formating the values as element instead of attributes before going from xml to json
<product>
<item>
<aa>
<name>024</name>
<value>123</value>
</aa>
<bbb>
<name>0105</name>
<value>123456</value>
</bbb>
<bbb>
<name>0122</name>
<value>T</value>
</bbb>
<aa>
<name>071</name>
<value>00000001</value>
</aa>
</item>
<item>
<aa>
<name>002</name>
<value>753</value>
</aa>
<aa>
<name>003</name>
<value>456</value>
</aa>
<bbb>
<name>0146</name>
<value>147852</value>
</bbb>
</item>
</product>
the current xls used for transform from xml to xml
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:c="myapp"
exclude-result-prefixes="c">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="c:item">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
outcome and desired json (well just imagine the last xml transformed in a json file)
{
{
"aa" : {"024":"123"}
"bbb" : {"0105","123456"}
"bbb" : {"0122","T"}
"aa" : {"071","00000001"}
}
{
{
...
}
}
**** Edited July 31th
output based on Michael Kay answer:
"aa" : {"024":"123"}"bbb" : {"0105":"123456"}"bbb" : {"0122":"T"}"aa" : {"071":"00000001"}"aa" : {"002":"753"}"aa" : {"003":"456"}"bbb" : {"0146":"147852"}
XLS used based on Michael Kay answer and generating above outcome
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:c="myapp" exclude-result-prefixes="c">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="c:item/*">
<xsl:text>"</xsl:text>
<xsl:value-of select="local-name()"/>
<xsl:text>" : {"</xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>":"</xsl:text>
<xsl:value-of select="@value"/>
<xsl:text>"}</xsl:text>
</xsl:template>
</xsl:stylesheet>
The XSLT you have shown is on the right path, but you are missing a few things
- No template handling the
c:item
itself to wrap the child nodes in{ }
- No output of commas and line-breaks to separate objects
- No handling of the root element
c:product
to create a child array (so you have valid JSON)
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:c="myapp" exclude-result-prefixes="c">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[c:item]">
<xsl:text>[ </xsl:text>
<xsl:apply-templates select="c:item"/>
<xsl:text>] </xsl:text>
</xsl:template>
<xsl:template match="c:item">
<xsl:text> { </xsl:text>
<xsl:apply-templates />
<xsl:text> }</xsl:text>
<xsl:if test="following-sibling::c:item">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="c:item/*">
<xsl:text> "</xsl:text>
<xsl:value-of select="local-name()" />
<xsl:text>" : {"</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>":"</xsl:text><xsl:value-of select="@value" />
<xsl:text>"}</xsl:text>
<xsl:if test="following-sibling::*">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
When you apply this XSLT to the following XML
<c:product xmlns:c="myapp">
<c:item cod="789">
<c:aa name="024" value="123"/>
<c:bbb name="0105" value="123456"/>
<c:bbb name="0122" value="T"/>
<c:aa name="071" value="00000001"/>
</c:item>
<c:item package="123" cod="11111">
<c:aa name="002" value="753"/>
<c:aa name="003" value="456"/>
<c:bbb name="0146" value="147852"/>
</c:item>
</c:product>
The following is output
[
{
"aa" : {"024":"123"},
"bbb" : {"0105":"123456"},
"bbb" : {"0122":"T"},
"aa" : {"071":"00000001"}
},
{
"aa" : {"002":"753"},
"aa" : {"003":"456"},
"bbb" : {"0146":"147852"}
}
]
This doesn't actually match the desired output in your question, but the output you are shown isn't actually valid JSON.
See this answer in action at http://xsltransform.net/ejivdGD
这篇关于如何从基于属性的xml转换为json,并通过使用XSLT / XSL忽略来自特定元素的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!