【问题标题】:how transform from xml based on attributes to json and ignore the attributes from especific elements by using XSLT/XSL如何使用 XSLT/XSL 从基于属性的 xml 转换为 json 并忽略特定元素的属性
【发布时间】:2016-07-30 02:33:58
【问题描述】:

我相信我的问题很好地说明了我想要做什么。顺便说一句,在传入的 xml 和所需的 json 输出下方找到。

我在这里找到了一个很好的答案Problems converting XML to JSON using XSLT 关于如何从 xml 移动到 json 但我的 xml 有点不同。请注意,下面的值是属性的一部分。另外,我想忽略 c:item 的属性。换句话说,必须忽略 cod 和 package。我知道如何将基于属性的此类 xml 转换为基于元素值的另一个 xml,然后将这个新的 xml 转换为 json 格式,但在我看来第一步(从 xml 到另一个 xml)有点奇怪,因为我只想要 json .我知道从 xml 到 xml,这要归功于这里提供的出色答案while transforming attributes to element with XSLT how ignore only the attributes in parent element

传入的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>

输出 xml 只是为了举例说明我必须与我当前的 knolege 做的额外步骤,即,如果我有义务从 xml 到 xml 执行额外的步骤,只是为了从 c:item 中取出属性并将值格式化为从 xml 到 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>

用于从 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="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>

结果和期望的 json(想象一下最后一个 xml 转换成 json 文件)

    {
       {
         "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"}"aa" : {"071":"00000001"}"aa" : {"002":"753"}"aa" : {"003":"456"}"bbb" : {"0146":"147852"}

根据 Michael Kay 的回答使用 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="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>

【问题讨论】:

  • “我相信我的问题提供了一个好主意。” - 这由读者来判断。请注意,您实际上并没有 一个问题(除了在标题...之类的)。您还可以在拼写、语法、标点符号和一般可读性方面做得更好。 (IMO,请摆脱关于为什么您认为您的问题是一个好问题的令人信服的胡扯,并专注于实际上使它成为一个好问题。)
  • 斯蒂芬,如果我在标题中提出问题,那么我确实提出了问题。我在这里读过好几次有人在我开始我的问题时开始类似,这是我第一次看到有人抱怨。我在哪里说我做了一个好问题?我告诉有人为我之前的问题提供了一个很好的答案(与你所说的完全相反)。关于拼写和语法,不幸的是英语不是我的母语,我总是尽我所能避免英语错误,但我不知道你在说哪个错误。最后,我的问题到底有什么问题?
  • 任何浪费>>读者
  • 所需的以两个左大括号 { { 开头的“JSON”根本不是有效的 JSON。
  • 正确,打错了。

标签: java xml xslt dom xls


【解决方案1】:

您展示的 XSLT 走在了正确的道路上,但是您遗漏了一些东西

  1. 没有模板处理 c:item 本身以将子节点包装在 { }
  2. 不输出逗号和换行符来分隔对象
  3. 不处理根元素 c:product 来创建子数组(因此您有有效的 JSON)

试试这个 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>

当您将此 XSLT 应用于以下 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>

以下是输出

[
  {
    "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查看这个答案

【讨论】:

  • Tim C,你完美地回答了我的疑问。我只想在这个 xsl 中做一个小调整,这个 xsl 最初并没有被问到。因为,在我的现实世界中,我发现 aa 将始终是两位数字代码(例如 99),而 bbb 将始终是三位数字代码(例如 999)我知道我可以拥有一个没有“aa”和“的有效 json 文件bb”。我该怎么做?我在这里提出了一个新问题,提出了这个具体的疑问stackoverflow.com/questions/38701874/…
【解决方案2】:

来自

<c:aa name="024" value="123"/>

"aa" : {"024":"123"}

完全是微不足道的:它只是

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

我不太明白你为什么会遇到问题。

【讨论】:

  • 迈克尔,感谢您的回答,但我肯定错过了您的部分答案或您希望我已经知道的 xls 的一些基本想法。请注意,我尝试了您的建议,但首先,我没有得到有效的 json,其次我正在“混合”这些项目。请复制我的输入 xml 并针对您的 xls 建议运行,您会发现我无法区分哪个“aa”或“bbb”属于第一项,哪个属于最后一项。我想在转换过程中删除 cod 和 package 属性,但我自然不想把第一项和第二项弄乱
  • 您仍然将 XSL 拼写为“xls”这一事实表明您对这门语言非常陌生,而且很难知道如何回答非常原始的初学者提出的问题,因为我们不知道你知道多少。用教程回答问题是不可能或不合适的,在我看来,给出一个复杂的工作解决方案也不合适,因为我认为你需要自己解决这个问题:一个好的 SO 问题的重点在于在一个你被卡住的关键领域,很难在你的问题中看到你的阻碍者在哪里。
  • 迈克尔,我对这个话题很谦虚,我很感谢你为帮助我所做的努力。
猜你喜欢
  • 2010-10-13
  • 2018-09-22
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2020-10-13
相关资源
最近更新 更多