首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将子节点和子元素从xml转换为json

如何将子节点和子元素从xml转换为json
EN

Stack Overflow用户
提问于 2021-05-17 15:27:07
回答 1查看 46关注 0票数 0

我们正在尝试做xml到json的转换。子元素“EmployeeCode”无法识别。错误:在第15行执行XSLT时出错:的xml-to-json:子元素必须有一个键属性。需要考虑xml到json转换中的子元素和子元素。

xmlFile:

代码语言:javascript
复制
<root>
    <Name>Alex</Name>
    <Age>42</Age>
    <item>
        <number>314</number>
        <name>foo</name>
        <EmployeeCode>
            <id>F21</id>
            <Department>
                <Designation>Engineer</Designation>
            </Department>
            <Status>Contractor</Status>
        </EmployeeCode>
    </item>
    <item>
        <number>42</number>
        <name>bar</name>
        <EmployeeCode>
            <id>F24</id>
            <Department>
                <Designation>Manager</Designation>
            </Department>
            <Status>Full-time</Status>
        </EmployeeCode>
    </item>
    <data>test</data>
</root>

xslcode:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
      <xsl:variable name="json-xml">
          <xsl:apply-templates/>
      </xsl:variable>
      <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
  </xsl:template>
  
  <xsl:template match="*[not(*)]">
    <string key="{local-name()}">{.}</string>
  </xsl:template>
  
  <xsl:template match="*[not(*) and . castable as xs:double]">
    <number key="{local-name()}">{.}</number>
  </xsl:template>
  
  <xsl:template match="*[*]">
      <map>
          <xsl:for-each-group select="*" group-by="node-name()">
              <xsl:choose>
                  <xsl:when test="current-group()[2]">
                      <array key="{local-name()}">
                          <xsl:apply-templates select="current-group()"/>
                      </array>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"/>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>
      </map>
  </xsl:template>
  
      <xsl:template match="node()|@*">        
        <!-- Including any attributes it has and any child nodes -->
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

</xsl:stylesheet>

预期的Json文件:

代码语言:javascript
复制
{
    "Name": "Alex",
    "Age": 42,
    "item": [
      {
        "number": 314,
        "name": "foo",
        "EmployeeCode": {
          "id": "F21",
          "Department": {
            "Designation": "Engineer"
          },
          "Status": "Contractor"
        }
      },
      {
        "number": 42,
        "name": "bar",
        "EmployeeCode": {
          "id": "F24",
          "Department": {
            "Designation": "Manager"
          },
          "Status": "Full-time"
        }
      }
    ],
    "data": "test"
  }
EN

回答 1

Stack Overflow用户

发布于 2021-05-17 16:50:59

这是对前面代码进行改进的尝试:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
      <xsl:variable name="json-xml">
          <xsl:apply-templates/>
      </xsl:variable>
      <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
  </xsl:template>
  
  <xsl:template match="*[not(*)]">
    <string key="{local-name()}">{.}</string>
  </xsl:template>
  
  <xsl:template match="*[not(*) and . castable as xs:double]">
    <number key="{local-name()}">{.}</number>
  </xsl:template>
  
  <xsl:template match="*[*]">
    <xsl:param name="key" as="xs:boolean" select="false()"/>
    <map>
      <xsl:if test="$key">
        <xsl:attribute name="key" select="local-name()"/>
      </xsl:if>
      <xsl:for-each-group select="*" group-by="node-name()">
          <xsl:choose>
              <xsl:when test="current-group()[2]">
                  <array key="{local-name()}">
                      <xsl:apply-templates select="current-group()">
                        <xsl:with-param name="key" select="false()"/>
                      </xsl:apply-templates>
                  </array>
              </xsl:when>
              <xsl:otherwise>
                  <xsl:apply-templates select="current-group()">
                    <xsl:with-param name="key" select="true()"/>
                  </xsl:apply-templates>
              </xsl:otherwise>
          </xsl:choose>
      </xsl:for-each-group>
    </map>
  </xsl:template>

</xsl:stylesheet>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67565547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档