首页 > 解决方案 > 如何获取与父元素属性 (xslt) 不匹配的最后一个子元素属性?

问题描述

我正在尝试获取没有与父元素的属性之一匹配的属性的父元素的最后一个子元素?我已经为此工作了一段时间,到目前为止空手而归。

我可以轻松获取最后一个元素并查看它的属性是否匹配。如果没有,我可以检查 last-1,但是如何递归地或使用内置函数来执行此操作?

在下面的示例中,父元素 (MainRecord) 具有 3 个可能存在或可能为空的属性(Data1、Data2、Data3)。子元素具有一个数据属性,该属性可能是也可能不是父数据属性之一。

所以对于 RecordNumber=1,我需要 Cloud,因为 Rainbow 在父级中。记录 3 一直上升到 Sunshine,因为 Flower、Cloud 和 Rainbow 都在父项中。

XML 文件:

<MainRecord Data1="" Data2="" Data3="Rainbow" RecordNumber="1">
    <AuditRecord Data="Sky" SomomethingElse="Hi"/>
    <AuditRecord Data="Sunshine" SomomethingElse="Yo"/>
    <AuditRecord Data="Flower" SomomethingElse="Do"/>
    <AuditRecord Data="Cloud" SomomethingElse="Re"/>
    <AuditRecord Data="Rainbow" SomomethingElse="Mi"/>
</MainRecord>
<MainRecord Data1="" Data2="Cloud" Data3="Rainbow" RecordNumber="2">
    <AuditRecord Data="Sky" SomomethingElse="Hi"/>
    <AuditRecord Data="Sunshine" SomomethingElse="Yo"/>
    <AuditRecord Data="Flower" SomomethingElse="Do"/>
    <AuditRecord Data="Cloud" SomomethingElse="Re"/>
    <AuditRecord Data="Rainbow" SomomethingElse="Mi"/>
</MainRecord>
<MainRecord Data1="Flower" Data2="Cloud" Data3="Rainbow" RecordNumber="3">
    <AuditRecord Data="Sky" SomomethingElse="Hi"/>
    <AuditRecord Data="Sunshine" SomomethingElse="Yo"/>
    <AuditRecord Data="Flower" SomomethingElse="Do"/>
    <AuditRecord Data="Cloud" SomomethingElse="Re"/>
    <AuditRecord Data="Rainbow" SomomethingElse="Mi"/>
</MainRecord>
<MainRecord Data1="Cloud" Data2="Flower" Data3="" RecordNumber="4">
    <AuditRecord Data="Sky" SomomethingElse="Hi"/>
    <AuditRecord Data="Sunshine" SomomethingElse="Yo"/>
    <AuditRecord Data="Flower" SomomethingElse="Do"/>
    <AuditRecord Data="Cloud" SomomethingElse="Re"/>
    <AuditRecord Data="Rainbow" SomomethingElse="Mi"/>
</MainRecord>
<MainRecord Data1="" Data2="" Data3="" RecordNumber="5">
    <AuditRecord Data="Sky" SomomethingElse="Hi"/>
    <AuditRecord Data="Sunshine" SomomethingElse="Yo"/>
    <AuditRecord Data="Flower" SomomethingElse="Do"/>
    <AuditRecord Data="Cloud" SomomethingElse="Re"/>
    <AuditRecord Data="Rainbow" SomomethingElse="Mi"/>
</MainRecord>

转换后的期望输出:

<MainRecord RecordNumber="1" MaxData="Cloud"/>
<MainRecord RecordNumber="2" MaxData="Flower"/>
<MainRecord RecordNumber="3" MaxData="Sunshine"/>
<MainRecord RecordNumber="4" MaxData="Rainbow"/>
<MainRecord RecordNumber="5" MaxData="Rainbow"/>

这是我玩这个。maxData 的变量不起作用,我确信这不是正确的方法,但我被卡住了。

<MainRecords>
    <xsl:for-each select="MainRecord">
        <xsl:attribute name="RecordNumber"><xsl:value-of select="@RecordNumber"/></xsl:attribute>
        <xsl:variable name="maxData"/>
        <xsl:for-each select="AuditRecord">
            <xsl:if test="not(@Data=@Data1) and not(@Data=@Data2) and not(@Data=@Data3)">
                <xsl:variable name="maxDate"><xsl:value-of select="@Data"/></xsl:variable>
            </xsl:if>
        </xsl:for-each>

        <xsl:attribute name="Count"><xsl:value-of select="count(AuditRecord)"/></xsl:attribute>
        <xsl:attribute name="LastDataThatDoesntMatch"><xsl:value-of select="$maxDate"/></xsl:attribute>
        <xsl:attribute name="Last"><xsl:value-of select="ItemAudit[last()]/@Date"/></xsl:attribute>
        <xsl:attribute name="2ndLast"><xsl:value-of select="ItemAudit[last()-1]/@Date"/></xsl:attribute>
        <xsl:attribute name="3rdLast"><xsl:value-of select="ItemAudit[last()-2]/@Date"/></xsl:attribute>
        <xsl:attribute name="4thLast"><xsl:value-of select="ItemAudit[last()-3]/@Date"/></xsl:attribute>
    </xsl:for-each>
</MainRecords>

我很感激任何帮助。这显然不是实际数据——只是问题的一个简单版本,没有专有数据。不是学校项目,这是我第一次在项目中使用 xslt,所以这对我来说有点陌生。

标签: xmlxslt

解决方案


我想你只是想要

  <xsl:template match="MainRecord">
      <MainRecord RecordNumber="{@RecordNumber}" MaxData="{AuditRecord[not(@Data = current()/@*[starts-with(local-name(), 'Data')])][last()]/@Data}"/>
  </xsl:template>

https://xsltfiddle.liberty-development.net/bnnZXc


推荐阅读