我仍然在用XSLT耳熟能詳,而且我在XSLT模板上遇到了麻煩。我試圖創建一個模板來匹配我的XML數據的每個縮進級別,但出於某種原因,無論我嘗試使用什麼樣的apply-templates調用,我只能打印第一個縮進級別..或者說,它只應用一個縮進級別,就好像它匹配出現的第一個模式,而忽略其餘的模式。有人可以告訴我有關XSLT語法的任何內容嗎?同樣的方法用於其他一些數據,並且工作得很好。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>
當我離開只是第一個應用模板調用,它給我的第一層,這是我應該想到,這是所有的第一層屬性標記......但如果我把在未來行,它應該匹配模板#2,它所做的只是在模板1的模式之後打印完全相同的數據,而不是匹配模板2的模式數據。爲什麼它忽略了我的其他模板?
我幾乎只是複製元素和parentID打印機的一些遺留代碼,所以我不確定這些,但是到目前爲止,我已經得到了正確的父母...... – 2013-02-11 19:49:10
@DarinBeaudreau'。 ./../* [1]'將選擇上下文節點的祖父母的第一個孩子。在某些情況下,這與上下文節點的父節點是相同的,但在大多數情況下不是。我上面的其他信息是否清除了您的困惑? – JLRishe 2013-02-11 21:01:59
是的,我不知道爲什麼我會在apply-templates調用中使用「匹配」...有時我會混淆屬性,但我認爲我已經明白了。至於祖父母/父母XPath ...它工作正常,所以我不明白問題在哪。 – 2013-02-11 21:55:52