【问题标题】:transform an xml into suitable text将 xml 转换为合适的文本
【发布时间】:2011-08-31 01:39:23
【问题描述】:

我有一个xml,看起来像这样

<person>
   <name>
      <name-first>foo</name-first>
      <name-last>bar</name-last>
   </name>
   <age>20</age>
   <city>nowhere</city>
 </person>

我想把它转换成

person:
   {
     name: {
             name-first:'foo', 
             name-last:'bar'  
           }, 
    age:'20',
    city:'nowhere' 
  }

提前致谢。

【问题讨论】:

  • 许多编程语言都有一个 XML 库,因此您可以轻松地创建一个快速程序来为您执行此操作。如果您最喜欢的语言没有 XML 库,您也可以使用字符串操作来做到这一点。
  • @ingo vals - 感谢您的回复,@oded - 我尝试了以下 w3.org/1999/XSL/Transform"> ,但我没有得到我想要的。请帮忙。
  • 好问题,+1。请参阅我的答案以获得完整、简短且简单的 XSLT 解决方案。

标签: xml xslt transform


【解决方案1】:

你想要的是一个 XML 到 JSON 的转换器。

试试这个:http://www.thomasfrank.se/xml_to_json.html

【讨论】:

  • 这正是我想要的。谢谢。
【解决方案2】:

这是一个示例 xsl 模板,它可以让您了解如何将 xml 转换为所需的输出:

<xsl:template match="person">
person:
   {
     name: {
             name-first:<xsl:value-of select="name/name-first"/>, 
             name-last:<xsl:value-of select="name/name-last"/>  
           }, 
    age:<xsl:value-of select="age"/>,
    city:<xsl:value-of select="city"/> 
  }
</xsl:template>

【讨论】:

  • 是的,没错。但是,我想要一种更通用的方法,而无需明确指定节点名称。我的意思是,如果我在我的 XML 中添加更多节点,XSL 仍然应该在没有任何修改的情况下提供输出。无论如何,感谢您的回复。
【解决方案3】:

有许多通用 XSLT 解决方案可用于将 XML 转换为 JSON 输出。

例如:

我通过 xml2json-xslt's xml2json.xslt 运行您的 XML 并生成以下 JSON 输出:

{
  "person":
     {
       "name":
         {
           "name-first":"foo",
           "name-last":"bar"
         },
         "age":20,
         "city":"nowhere"
      }
 }

【讨论】:

    【解决方案4】:

    这是一个简单的转换——开始

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output method="text"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:param name="pIndents" select="'  '"/>
    
     <xsl:template match="*[*]">
       <xsl:param name="pcurrentIndents" select="''"/>
         <xsl:value-of select="concat($pcurrentIndents, name(), ':')"/>
         <xsl:value-of select="concat('&#xA;',$pcurrentIndents, '{')"/>
          <xsl:apply-templates>
            <xsl:with-param name="pcurrentIndents" select=
             "concat($pcurrentIndents, $pIndents)"/>
          </xsl:apply-templates>
         <xsl:value-of select="concat('&#xA;',$pcurrentIndents,  '}')"/>
     </xsl:template>
    
     <xsl:template match="*[not(*)]">
      <xsl:param name="pcurrentIndents" select="''"/>
      <xsl:text>&#xA;</xsl:text>
      <xsl:value-of select="concat($pcurrentIndents, name(), ':')"/>
      <xsl:apply-templates/>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于提供的 XML 文档时

    <person>
        <name>
            <name-first>foo</name-first>
            <name-last>bar</name-last>
        </name>
        <age>20</age>
        <city>nowhere</city>
    </person>
    

    产生想要的正确结果

    person:
    {  name:
      {
        name-first:foo
        name-last:bar
      }
      age:20
      city:nowhere
    }
    

    解释

    1. 有两个模板匹配元素。

    2. 匹配*[*] 的模板匹配具有子元素的元素。它使用name() 函数生成当前匹配元素的名称,然后是: 字符,然后是NL 字符,当前缩进(空格数),最后是{ 字符。然后将模板应用于当前匹配元素的子节点,并使用 $pcurrentIndents 参数传递当前缩进随着空格字符的预定义增量而增加(如全局参数 $pIndents 中指定的那样)最后,在新行上并使用当前缩进,右花括号被放置。

    3. 匹配*[not(*)](没有任何子元素的元素)的模板类似,但更简单。它输出当前缩进处匹配元素的名称和: 字符。在此处应用模板会调用非元素节点的 XSLT 内置模板——在这种情况下,选择匹配文本节点的内置模板,它只是将文本节点复制到输出。

    【讨论】:

    • 感谢您的精彩回复。您的代码运行良好,但我仍然需要进行一些修改,例如 - 在行尾添加逗号 ','。如果你能分享/解释一下这段代码是如何工作的,我会很高兴,这将是一个很好的学习/理解 XML。
    • 感谢您的解释,我会尝试修改它以满足我的要求。
    猜你喜欢
    • 2012-02-06
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多