我仍然对 XSLT 感到困惑,而且我在使用 XSLT 模板时遇到了麻烦。我正在尝试制作一个模板来匹配我的 XML 数据的每个缩进级别,但由于某种原因,无论我尝试应用模板调用的哪种变体,我都只能打印第一个缩进级别。 . 或者更确切地说,它只应用一个缩进级别,就好像它匹配出现的第一个模式并忽略其余部分。有人可以判断我的 XSLT 语法是否有问题吗?同样的方法也用于其他一些数据,并且效果很好。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<config>
<xsl:apply-templates match="/Objects/*/*" /> <!-- Matches template #1 -->
<xsl:apply-templates match="/Objects/*/*/*" /> <!-- Matches template #2 -->
<xsl:apply-templates match="/Objects/*/*/*/*" /> <!-- Matches template #3 -->
<xsl:apply-templates match="/Objects/*/*/*/*/*" /> <!-- Matches template #4 -->
<xsl:apply-templates match="/Objects/*/*/*/*/*/*" /> <!-- Matches template #5 -->
<xsl:apply-templates match="/Objects/*/*/*/*/*/*/*" /> <!-- Matches template #6 -->
</config>
</xsl:template>
<!-- <xsl:template match="Object">
<element>
<typefield>Object</typefield>
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template> -->
<!-- Begin Template #1 -->
<xsl:template match="Object/*">
<element>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template>
<!-- End Template #1 -->
<!-- Begin Template #2 -->
<xsl:template match="Object/*/*">
<element2>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="parentIDPrinter" />
<xsl:call-template name="elementPrinter" />
</element2>
</xsl:template>
<!-- End Template #2 -->
<!-- Begin Template #3 -->
<xsl:template match="Object/*/*/*">
<element>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="gparentIDPrinter" />
<xsl:call-template name="parentIDPrinter" />
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template>
<!-- End Template #3 -->
<!-- Begin Template #4 -->
<xsl:template match="Object/*/*/*/*">
<element>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="gparentIDPrinter" />
<xsl:call-template name="parentIDPrinter" />
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template>
<!-- End Template #4 -->
<!-- Begin Template #5 -->
<xsl:template match="Object/*/*/*/*/*">
<element>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="gparentIDPrinter" />
<xsl:call-template name="parentIDPrinter" />
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template>
<!-- End Template #5 -->
<!-- Begin Template #6 -->
<xsl:template match="Object/*/*/*/*/*/*">
<element>
<typefield>
<xsl:value-of select="@Name" />
</typefield>
<xsl:call-template name="gparentIDPrinter" />
<xsl:call-template name="parentIDPrinter" />
<xsl:call-template name="elementPrinter" />
</element>
</xsl:template>
<!-- End Template #6 -->
<!-- Prints all elements within the matching node. -->
<xsl:template name="elementPrinter">
<xsl:for-each select="*">
<xsl:if test="text() != ''">
<xsl:choose>
<xsl:when test="@Name">
<xsl:variable name="eName">
<xsl:value-of select="@Name" />
</xsl:variable>
<xsl:element name="{$eName}">
<xsl:value-of select="text()" />
</xsl:element>
</xsl:when>
<xsl:when test="not(@Name)">
<xsl:variable name="eName">
<xsl:value-of select="@Type" />
</xsl:variable>
<xsl:element name="{$eName}">
<xsl:value-of select="text()" />
</xsl:element>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Prints a tag containing the name of the node's parent. -->
<xsl:template name="parentIDPrinter">
<xsl:for-each select="../../*[1]">
<xsl:choose>
<xsl:when test="./@Name">
<xsl:variable name="pName">
<xsl:value-of select="@Name" />
</xsl:variable>
<xsl:element name="parent">
<xsl:value-of select="$pName" />
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="pName">
<xsl:value-of select="@Type" />
</xsl:variable>
<xsl:element name="parent">
<xsl:value-of select="$pName" />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!-- Prints a tag containing the name of the node's grandparent. -->
<xsl:template name="gparentIDPrinter">
<xsl:for-each select="../../../../*[1]">
<xsl:choose>
<xsl:when test="./@Name">
<xsl:variable name="pName">
<xsl:value-of select="@Name" />
</xsl:variable>
<xsl:element name="grandparent">
<xsl:value-of select="$pName" />
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="pName">
<xsl:value-of select="@Type" />
</xsl:variable>
<xsl:element name="grandparent">
<xsl:value-of select="$pName" />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
不幸的是,我无法发布示例数据,但格式几乎就是这样。
<Objects>
<Object>
<Property Name="whatever">
<Property Name="whatever1.1">whatever</Property>
<Property Name="whatever1.2">whatever2</Property>
</Property>
<Property Name="whatever">
<Property Name="whatever1.1">whatever</Property>
<Property Name="whatever1.2">whatever2</Property>
</Property>
</Object>
<Object>
<Property Name="whatever">
<Property Name="whatever1.1">whatever</Property>
<Property Name="whatever1.2">whatever2</Property>
</Property>
<Property Name="whatever">
<Property Name="whatever1.1">whatever</Property>
<Property Name="whatever1.2">whatever2</Property>
</Property>
</Object>
</Objects>
当我只留下第一个 apply-templates 调用时,它给了我第一层,我应该期待,这是所有第一层属性标签......但是如果我放入下一行,它应该匹配模板# 2,它所做的只是在模板 1 的模式之后打印完全相同的数据,而不是匹配模板 2 的模式数据。为什么它忽略了我的其他模板?