我们有(可能是异常格式的)XML 文件,它们(非常简化)如下所示:
<Contacts>
<Contact>
<Private>
<Name>John Doe</Name>
<Address>Somewhere1</Address>
...
</Private>
</Contact>
<Contact>
<Business>
<Name>John Business</Name>
<Address>Somewhere2</Address>
<BusinessAddress>Somewhere3</BusinessAddress>
...
</Business>
</Contact>
...
</Contacts>
实际上,我们有几十种不同类型的“联系人”节点,它们具有更多属性,但其中一些属性在所有类型之间都是通用的……
我们目前使用样式表来格式化 XML 文件,该文件对每种类型的“联系人”节点的所有常见属性重复格式化:
<!-- ... loads of prologue code -->
<xsl:for-each select="Contacts/Contact/.">
<xsl:choose>
<xsl:when test="Private">
<!-- code to format each and every attribute of the current
"Contact" element, e.g.: -->
<td class="header">Private Contact</td>
<td class="detail"><xsl:value-of select="./Name"/></td>
<!-- ... -->
</xsl:when>
<xsl:when test="Business">
<!-- code to format each and every attribute of the current
"Contact" element, e.g.: -->
<td class="header">Business Contact/<td>
<td class="detail"><xsl:value-of select="./Name"/></td>
<!-- ... -->
</xsl:when>
<!-- ... -->
</xsl:choose>
</xsl:for-each>
但是我们越来越多的<Contact>
类型具有越来越多的属性,导致样式表长达一英里,所以我想将样式表简化如下:
<!-- ... loads of prologue code -->
<xsl:for-each select="Contacts/Contact/.">
<!-- loads of formatting stuff common to each "Contact" type, but with
some wording that's "Contact" type dependant, e.g. -->
<td class="header">**????** Contact</td>
<td class="detail"><xsl:value-of select="./Name"/></td>
<xsl:choose>
<xsl:when **????** = "Private">
<xsl:variable name="contactWhen">off</xsl:variable>
</xsl:when>
<xsl:when **????** = "Business">
<xsl:variable name="contactWhen">office</xsl:variable>
</xsl:when>
<!-- ... -->
</xsl:choose>
<td class="header">Contact/<td>
<td class="detail">Only during $contactWhen hours</td>
<xsl:choose>
<xsl:when test="Private">
<!-- code to format attributes specific for the current "Contact" -->
</xsl:when>
<xsl:when test="Business">
<!-- code to format attributes specific for the current "Contact" -->
</xsl:when>
<!-- ... -->
</xsl:choose>
</xsl:for-each>
如果上面的代码示例中有任何拼写错误或语法错误,我的借口是,但我对 XSLT 语法不是很熟悉,并且上面的大部分代码都是为了示例而手工制作的......
我的问题是我无法获得下节点的名称值Contact
,在这个例子中Private
或Business
。我已经尝试过使用我能想到的所有变体,无论是value-of select=
简单select= (a.o. "", ".", "./."
的 , Contacts/Contact
, Contacts/Contact/.
,[local-]name()
甚至Field[@name='.']
)。
有些尝试会产生错误,有些会导致空字符串,有些会返回父节点的名称 ie Contact
,有些会以单个字符串的形式返回所有从属属性的值(尽管没有属性名称)... :-(
我应该编写什么代码**????**
来测试当前节点的名称值,并最终根据该测试的结果为一些变量分配一个值?
感谢您的任何帮助,
尤尔
你好,
感谢您提供宝贵的意见,我肯定会考虑将这个样式表和其他一些类似的样式表转换为使用模板,但现在我面临着交付这个项目的压力。
我在“for-each”循环中和“选择”之前尝试了所有 3 个建议,但所有 3 个都失败了:
<td class="content2" colspan="2"><xsl:value-of select="ancestor::Record/child::*[1]name"/></td>
失败并出现 XML 错误:预期的 'EOF' 找到了 'name'
<td class="content2" colspan="2"><xsl:value-of select="name()"/></td>
返回“联系人”,而不是第一个孩子的名字
<xsl:variable name="contactType">
<xsl:choose>
<xsl:when test="Private">Private</xsl:when>
<xsl:when test="Business">Business</xsl:when>
</xsl:choose>
<td class="content2" colspan="2"><xsl:value-of select="$contactType"/></td>
</xsl:variable>
因 XML 错误而失败:无法解析对变量“contactType”的引用。该变量可能未定义或不在范围内。
这种行为是由内联代码而不是模板中的这些构造引起的吗?
请指教,
尤尔