XSLT 为这种需求提供了一个优雅的解决方案。例如,下面是一个示例转换,它适用于this page 上提供的 XML,并将其转换为同一页面上给出的 json。
<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:strip-space elements="*" />
<xsl:variable name="nl"><xsl:text>
</xsl:text></xsl:variable>
<xsl:variable name="q">"</xsl:variable>
<xsl:variable name="bInd" select="' '" />
<xsl:template match="glossary">
<xsl:value-of select="concat('{', $nl, $bInd, $q, local-name(.), $q, ' : {')" />
<xsl:apply-templates>
<xsl:with-param name="ind" select="concat($bInd, $bInd)" />
</xsl:apply-templates>
<xsl:value-of select="concat($nl, $bInd, '}', $nl, '}', $nl)" />
</xsl:template>
<xsl:template match="title">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, ' ', $q, local-name(.), $q, ' : ', $q, ., $q)" />
</xsl:template>
<!-- Other text elements -->
<xsl:template match="*">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, ', ', $q, local-name(.), $q, ' : ', $q, ., $q)" />
</xsl:template>
<xsl:template match="GlossEntry">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, $q, local-name(.), $q, ' : {')" />
<xsl:value-of select="concat($nl, $ind, $bInd, ' ',$q, 'ID', $q, ' : ', $q, @ID , $q)" />
<xsl:value-of select="concat($nl, $ind, $bInd, ', ', $q, 'SortAs', $q, ' : ', $q, @SortAs , $q)" />
<xsl:apply-templates>
<xsl:with-param name="ind" select="concat($ind, $bInd)" />
</xsl:apply-templates>
<xsl:value-of select="concat($nl, $ind, '}')" />
</xsl:template>
<xsl:template match="GlossDef">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, ', ', $q, local-name(.), $q, ' : {')" />
<xsl:value-of select="concat($nl, $ind, $bInd, ' ', $q, 'para', $q, ' : ', $q, para, $q)" />
<xsl:value-of select="concat($nl, $ind, $bInd, ', ', $q, 'GlossSeeAlso', $q, ' : [ ')" />
<xsl:for-each select="GlossSeeAlso">
<xsl:apply-templates select=".">
<xsl:with-param name="pos" select="position()" />
</xsl:apply-templates>
</xsl:for-each>
<xsl:value-of select="' ]'" />
<xsl:value-of select="concat($nl, $ind, '}')" />
</xsl:template>
<xsl:template match="GlossSeeAlso">
<xsl:param name="pos" />
<xsl:if test="$pos > 1">
<xsl:value-of select="', '" />
</xsl:if>
<xsl:value-of select="concat($q, @OtherTerm, $q)" />
</xsl:template>
<xsl:template match="GlossSee">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, ', ', $q, local-name(.), $q, ' : ', $q, @OtherTerm, $q)" />
</xsl:template>
<xsl:template match="GlossDiv | GlossList">
<xsl:param name="ind" />
<xsl:value-of select="concat($nl, $ind, ', ', $q, local-name(.), $q, ' : {')" />
<xsl:apply-templates>
<xsl:with-param name="ind" select="concat($ind, $bInd)" />
</xsl:apply-templates>
<xsl:value-of select="concat($nl, $ind, '}')" />
</xsl:template>
</xsl:transform>
此示例转换是 XSLT 1.0。您可以通过在 XML 文件中添加对它的引用并在 Web 浏览器中加载 XML 文件来测试它。
例如,如果上述转换存储在 test.xsl 中,则将 XML 放在 test.xml 中,并像这样引用转换:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<glossary>
<title>example glossary</title>
<GlossDiv>
<title>S</title>
<GlossList>
<GlossEntry ID="SGML" SortAs="SGML">
<GlossTerm>Standard Generalized Markup Language</GlossTerm>
<Acronym>SGML</Acronym>
<Abbrev>ISO 8879:1986</Abbrev>
<GlossDef>
<para>A meta-markup language, used to create markup languages such as DocBook.</para>
<GlossSeeAlso OtherTerm="GML" />
<GlossSeeAlso OtherTerm="XML" />
</GlossDef>
<GlossSee OtherTerm="markup" />
</GlossEntry>
</GlossList>
</GlossDiv>
</glossary>