【问题标题】:XSLT to concat attributes from multiple nodes into a single valueXSLT 将来自多个节点的属性连接成单个值
【发布时间】: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 属性的&lt;LandParcel /&gt; 节点传递给模板,则输出将是相同的。
  • 您使用哪个版本的 XSLT?

标签: xml xslt xslt-1.0


【解决方案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
    • 我给你发了我的电子邮件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多