XSLT 将来自多个节点的属性连接成单个值
Posted
技术标签:
【中文标题】XSLT 将来自多个节点的属性连接成单个值【英文标题】:XSLT to concat attributes from multiple nodes into a single value 【发布时间】:2021-10-31 13:11:09 【问题描述】:我想创建一个接受node
参数的XSLT 1.0 模板。该模板将连接每个节点的@lot
、@plan_type
和@plan
属性,用逗号连接每个节点结果并输出一个字符串。请参阅下面的示例 XML。
<?xml version="1.0" encoding="UTF-8"?>
<RealEstate unique_id="045dcd20-0a69-4f2a-9bfa-c6b3e9b03281">
<Title id="23bccbb0-2699-44bf-a672-9d2a27344254"
instruction_id="10752681" is_primary="Yes" lot="184" plan="1212069"
plan_type="DepositedPlan" tenure_type="Freehold" type="Torrens" />
<Title id="045dcd20-0a69-4f2a-9bfa-c6b3e9b03281"
instruction_id="10752681" is_primary="No" lot="185" plan="1212073"
plan_type="DepositedPlan" tenure_type="Freehold" type="Torrens" />
<Title id="c6b3e9b0-4f2a-44bf-a672-23bccbb04254"
instruction_id="10752681" is_primary="No" lot="186" plan="1213002"
plan_type="DepositedPlan" tenure_type="Freehold" type="Torrens" />
</RealEstate>
Title
节点将被传递给node
参数。然后将循环每个Title
节点以构建和输出字符串Lot 184 DepositedPlan 1212069, Lot 185 DepositedPlan 1212073, Lot 186 DepositedPlan 1213002
【问题讨论】:
好吧,你试过什么?像Title
这样的元素节点实际上是使用路径Title
选择的,名为lot
的属性是使用@lot
选择的,正如您已经展示的那样,连接值的函数被命名为concat
,那么您在哪里卡住了?
我看不出参数在这里扮演什么角色。您是否希望 Title 以外的元素具有相同的属性?
感谢马丁和迈克尔。参数的作用是使模板可以内联用作更大模板的一部分,并在 Altova MapForce 设计中“映射”输入和输出。
它也会更通用,因此如果将具有@lot
、@plan
和@plan_type
属性的<LandParcel />
节点传递给模板,则输出将是相同的。
您使用哪个版本的 XSLT?
【参考方案1】:
在 XSLT 2 及更高版本中我会使用
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="//Title"/>
</xsl:template>
<xsl:template match="Title">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="@lot, @plan_type, @plan" separator=" "/>
</xsl:template>
在 XSLT 1 中,最后一个模板是
<xsl:template match="Title">
<xsl:if test="position() > 1">, </xsl:if>
<xsl:value-of select="concat(@lot, ' ', @plan_type, ' ', @plan)"/>
</xsl:template>
【讨论】:
【参考方案2】:如果您想要一个通用模板,可以从作为参数传递给它的元素中提取属性,请尝试以下操作:
XSLT 1.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/RealEstate">
<xsl:call-template name="get-attributes">
<xsl:with-param name="elements" select="Title"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="get-attributes">
<xsl:param name="elements" select="/.."/>
<xsl:variable name="elem" select="$elements[1]" />
<!-- output -->
<xsl:value-of select="$elem/@lot"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$elem/@plan_type"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$elem/@plan"/>
<!-- continue -->
<xsl:if test="count($elements) > 1">
<xsl:text>, </xsl:text>
<!-- recursive call -->
<xsl:call-template name="get-attributes">
<xsl:with-param name="elements" select="$elements[position() > 1]"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,这将产生:
结果
184 DepositedPlan 1212069, 185 DepositedPlan 1212073, 186 DepositedPlan 1213002
请注意,传递给命名模板的参数是节点集,而不是字符串。
【讨论】:
优雅的解决方案和一些摆弄应该能够满足我的需求。我很乐意聘请您的专业知识,因为我需要进一步的 XSLT 模板作为我正在从事的项目的一部分的功能。请联系evosys.com.au/contact 我给你发了我的电子邮件。以上是关于XSLT 将来自多个节点的属性连接成单个值的主要内容,如果未能解决你的问题,请参考以下文章