如何从基于属性的 xml 转换为 json 并使用 XSLT/XSL 忽略特定元素的属性

how transform from xml based on attributes to json and ignore the attributes from especific elements by using XSLT/XSL

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

我在这里找到了一个很好的答案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

传入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 只是为了举例说明我必须用我当前的知识做的额外步骤,即,如果我有义务执行从 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>

来自

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

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

您显示的 XSLT 是在正确的路径上,但您遗漏了一些东西

  1. 没有模板处理 c:item 本身来包装 { }
  2. 中的子节点
  3. 不输出分隔对象的逗号和换行符
  4. 没有处理根元素 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

查看这个答案