假设我有以下xml:
<parent>
<child1 attr1="value" attr2="value" attr3="value"/>
<child1 attr1="value" attr2="value" attr3="value"/>
<child1 attr1="value" attr2="value" attr3="value"/>
</parent>
我想将 child1 类型的所有元素作为行放入由每个属性的列组成的表中 - 这很简单。但问题是,子元素的类型和子元素属性的数量/类型在父的实例之间有所不同。以下是父的某些实例可能包含
的示例<parent>
<child2 attr1="value" attr2="value" attr3="value" attr4="value"/>
<child2 attr1="value" attr2="value" attr3="value" attr4="value"/>
<child2 attr1="value" attr2="value" attr3="value" attr4="value"/>
</parent>
好消息是父节点中永远不会有两种类型的子元素,所以只要我为每种可能类型的子元素及其相关属性都有一个when子句,我就能做到这一点。坏消息是,儿童元素存在很多变化,需要花费很长时间才能确保我对每一个元素都有所了解。
我的问题是 - 有没有办法不加选择地为每个选择所有子元素而不查找特定类型,同时自动选择所有子元素属性为表格式,而不明确指定每个属性的内容foreach:
<td><xsl:value-of select="attr1"/></td>
这将有望产生不同类型的表,具体取决于父实例中子元素的类型及其相关的属性变化。
这可能还是我运气不好?
答案 0 :(得分:0)
当然,这是可能的。假设您希望每个<parent>
节点变为<table>
。 (显然,您会将select
XPath调整到传入文档中parent
节点的真实位置。)
<xsl:template match="/">
<xsl:apply-templates select="indoc/parent"/>
</xsl:template>
<xsl:template match="parent">
<table>
<xsl:apply-templates/>
</table>
</xsl:template>
现在,让我们说你真的关心元素名称,并且只想将childnnn
个节点变成行。我们会for-each
将每个属性(@*
XPath)转换为<td>
。
<xsl:template match="*[starts-with(local-name(), 'child')]">
<tr>
<xsl:for-each select="@*">
<td>
<xsl:value-of select="concat(local-name(), ':', .)"/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
如果您真的希望 <parent>
下的每个节点变成一行,无论元素名称是什么,您都可以将其压缩为两级嵌套{{1或者使用模板模式:
for-each