如何通过XLT Transform删除json的根元素

时间:2017-12-14 12:46:12

标签: json xml xslt

我有一个xml,我想要转换并传递给API,但我正在进行的转换有太多嵌套对象,并且想要在开始时将块移除到看起来像这样的json;

      {
"Body" : [

{
"Code" : "HOT", 
"Name" : "SIDE", 
"Type" : "AADULT", 
"Sec" : "MSec", 
"ardge" : "Adult", 
"Nder" : "F", 
"TBC" : "21", 
"BO" : "14", 
"DBOC" : "0", 
"LBC" : "5", 
"AB" : "2"
}, 

{
"Code" : "HOT", 
"Name" : "DARS", 
"Type" : "AADULT", 
"Sec" : "MSec", 
"ardge" : "OADULT", 
"Nder" : "U", 
"TBC" : "20", 
"BO" : "16", 
"DBOC" : "0", 
"LBC" : "2", 
"AB" : "2"
}
]
"Code" : "HOT", 
"Date" : "2017-12-08 11:22:34.658", 
}  

这是原始的xml

<?xml version="1.0" encoding="UTF-8"?>
<Message>
      <Code>HOT</Code>
      <Date>2017-12-08 11:22:34.658</Date>
   <Body>
      <Code>HOT</Code>
      <Name>SIDE</Name>
      <Type>AADULT</Type>
      <Sec>MSec</Sec>
      <ardge>Adult</ardge>
      <Nder>F</Nder>
      <TBC>21</TBC>
      <BO>14</BO>
      <DBOC>0</DBOC>
      <LBC>5</LBC>
      <AB>2</AB>
   </Body>
   <Body>
      <Code>HOT</Code>
      <Name>DARS</Name>
      <Type>AADULT</Type>
      <Sec>MSec</Sec>
      <ardge>OADULT</ardge>
      <Nder>U</Nder>
      <TBC>20</TBC>
      <BO>16</BO>
      <DBOC>0</DBOC>
      <LBC>2</LBC>
      <AB>2</AB>
   </Body>
</Message>

这是我正在使用的XLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="yes"/>
    <xsl:template match="/*[node()]">
        <xsl:text>{</xsl:text><xsl:text>&#xa;</xsl:text>
        <xsl:apply-templates select="." mode="detect" />
  <xsl:text>&#xa;</xsl:text>
        <xsl:text>}</xsl:text>
    </xsl:template>
    <xsl:template match="*" mode="detect">
        <xsl:choose>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current()) and name(following-sibling::*[1]) != name(current())">
                    <xsl:apply-templates select="." mode="obj-content" />
     <xsl:text>&#xa;</xsl:text>
                <xsl:text>]</xsl:text>
                <xsl:if test="count(following-sibling::*[name() != name(current())]) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="name(preceding-sibling::*[1]) = name(current())">
                    <xsl:apply-templates select="." mode="obj-content" />
                    <xsl:if test="name(following-sibling::*) = name(current())">, </xsl:if>
            </xsl:when>
            <xsl:when test="following-sibling::*[1][name() = name(current())]">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/><xsl:text>" : [</xsl:text>
        <xsl:text>&#xa;</xsl:text>
                    <xsl:apply-templates select="." mode="obj-content" /><xsl:text>, </xsl:text>
     <xsl:text>&#xa;</xsl:text>
            </xsl:when>
            <xsl:when test="count(./child::*) > 0 or count(@*) > 0">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : <xsl:apply-templates select="." mode="obj-content" />
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
            </xsl:when>
            <xsl:when test="count(./child::*) = 0">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:apply-templates select="."/><xsl:text>"</xsl:text>
                <xsl:if test="count(following-sibling::*) &gt; 0">, </xsl:if>
    <xsl:text>&#xa;</xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*" mode="obj-content">
     <xsl:text>&#xa;</xsl:text>
        <xsl:text>{</xsl:text>
  <xsl:text>&#xa;</xsl:text>
            <xsl:apply-templates select="@*" mode="attr" />
            <xsl:if test="count(@*) &gt; 0 and (count(child::*) &gt; 0 or text())">, </xsl:if>
            <xsl:apply-templates select="./*" mode="detect" />
            <xsl:if test="count(child::*) = 0 and text() and not(@*)">
                <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="text()"/><xsl:text>"</xsl:text>
            </xsl:if>
            <xsl:if test="count(child::*) = 0 and text() and @*">
                <xsl:text>"text" : "</xsl:text><xsl:value-of select="text()"/><xsl:text>"</xsl:text>
            </xsl:if>
        <xsl:text>}</xsl:text>
        <xsl:if test="position() &lt; last()">, </xsl:if>
    </xsl:template>
    <xsl:template match="@*" mode="attr">
        <xsl:text>"</xsl:text><xsl:value-of select="name()"/>" : "<xsl:value-of select="."/><xsl:text>"</xsl:text>
        <xsl:if test="position() &lt; last()">,</xsl:if>
    </xsl:template>
    <xsl:template match="node/@TEXT | text()" name="removeBreaks">
        <xsl:param name="pText" select="normalize-space(.)"/>
        <xsl:choose>
            <xsl:when test="not(contains($pText, '&#xA;'))"><xsl:copy-of select="$pText"/></xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(substring-before($pText, '&#xD;&#xA;'), ' ')"/>
                <xsl:call-template name="removeBreaks">
                    <xsl:with-param name="pText" select="substring-after($pText, '&#xD;&#xA;')"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

这就是我目前所得到的

{
"Message" : 
{
"Code" : "HOT", 
"Date" : "2017-12-08 11:22:34.658", 
"Body" : [

{
"Code" : "HOT", 
"Name" : "SIDE", 
"Type" : "AADULT", 
"Sec" : "MSec", 
"ardge" : "Adult", 
"Nder" : "F", 
"TBC" : "21", 
"BO" : "14", 
"DBOC" : "0", 
"LBC" : "5", 
"AB" : "2"
}, 

{
"Code" : "HOT", 
"Name" : "DARS", 
"Type" : "AADULT", 
"Sec" : "MSec", 
"ardge" : "OADULT", 
"Nder" : "U", 
"TBC" : "20", 
"BO" : "16", 
"DBOC" : "0", 
"LBC" : "2", 
"AB" : "2"
}
]}
}

1 个答案:

答案 0 :(得分:0)

你让它太复杂了。试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>

  <xsl:strip-space elements="*"/>

  <xsl:variable name="quot">"</xsl:variable>

  <xsl:template match="/">
    <xsl:text>{&#xa;</xsl:text>
    <xsl:apply-templates/>
    <xsl:text>&#xa;}</xsl:text>
  </xsl:template>

  <xsl:template match="Message">
    <xsl:text>"Body" : [</xsl:text>
    <xsl:apply-templates select="Body"/>
    <xsl:text>],&#xa;</xsl:text>
    <xsl:apply-templates select="*[not(self::Body)]"/>
  </xsl:template>

  <xsl:template match="Body" priority="2">
    <xsl:if test="position() != 1">,&#xa;</xsl:if>
    <xsl:text>{</xsl:text>
    <xsl:apply-templates/>
    <xsl:text>}</xsl:text>
  </xsl:template>

  <xsl:template match="Body/* | Message/*" priority="1">
    <xsl:if test="position() != 1">,&#xa;</xsl:if>
    <xsl:value-of select="concat($quot, name(), $quot, ':', $quot, string(.), $quot)"/>
  </xsl:template>

</xsl:stylesheet>