[英]Nested XML processing with XSLT
我有一個具有以下結構的XML文檔:
例如:
<DataModel>
<String name="a">aaa</String>
<Integer name="b">bbb</Integer>
<Node name="n1">
<String name="k">kkk</String>
<Integer name="l">lll</Integer>
<Node name="n2">
<String name="x">xxx</String>
</Node>
</Node>
</DataModel>
我想處理此XML,將輸出展平,但是將層次結構引入命名中,如下所示:
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<tr>
<td>a</td>
<td>aaa</td>
</tr>
<tr>
<td>b</td>
<td>bbb</td>
</tr>
<tr>
<td>n1.k</td>
<td>kkk</td>
</tr>
<tr>
<td>n1.l</td>
<td>lll</td>
</tr>
<tr>
<td>n1.n2.x</td>
<td>xxx</td>
</tr>
</table>
任何想法如何做到這一點?
使用此模板:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="DataModel">
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<xsl:apply-templates select="*"/>
</table>
</xsl:template>
<xsl:template match="*">
<tr>
<td>
<xsl:for-each select="ancestor::Node">
<xsl:value-of select="concat(@name, '.')"/>
</xsl:for-each>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="Node">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
應用於XML:
<DataModel>
<String name="a">aaa</String>
<Integer name="b">bbb</Integer>
<Node name="n1">
<String name="k">kkk</String>
<Integer name="l">lll</Integer>
<Node name="n2">
<String name="x">xxx</String>
</Node>
</Node>
</DataModel>
將產生所需的輸出:
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<tr>
<td>a</td>
<td>aaa</td>
</tr>
<tr>
<td>b</td>
<td>bbb</td>
</tr>
<tr>
<td>n1.k</td>
<td>kkk</td>
</tr>
<tr>
<td>n1.l</td>
<td>lll</td>
</tr>
<tr>
<td>n1.n2.x</td>
<td>xxx</td>
</tr>
</table>
該模板支持任何嵌套深度,這要感謝與祖先的 for-each :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="DataModel">
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<xsl:apply-templates select="*"/>
</table>
</xsl:template>
<xsl:template match="Node">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="String|Integer">
<tr>
<td>
<xsl:for-each select="ancestor::Node">
<xsl:value-of select="concat(@name, '.')"/>
</xsl:for-each>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>
因此結果完全符合要求,包括最后一行:
...
<tr>
<td>n1.n2.x</td>
<td>xxx</td>
</tr>
</table>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.