如何从基于属性的xml转换为json,并通过使用XSLT / XSL忽略来自特定元素的属性 [英] how transform from xml based on attributes to json and ignore the attributes from especific elements by using XSLT/XSL

查看:114
本文介绍了如何从基于属性的xml转换为json,并通过使用XSLT / XSL忽略来自特定元素的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我的问题提供了一个好主意,我想做什么。 BTW,找到下面的输入xml和所需的json输出。



我在这里找到了一个很好的答案使用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是在正确的路径上,但你缺少一些东西


  1. 没有模板处理 c:item 本身将子节点包裹在 {}

  2. 不输出逗号和换行符来分隔对象

  3. 没有处理根元素 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

  1. No template handling the c:item itself to wrap the child nodes in { }
  2. No output of commas and line-breaks to separate objects
  3. 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>[&#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:text>
        <xsl:apply-templates />
    <xsl:text>  }</xsl:text>
    <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>

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆