【问题标题】:Extract value from one XML while matching template in other XML using XSLT使用 XSLT 从一个 XML 中提取值,同时匹配其他 XML 中的模板
【发布时间】:2020-06-04 13:19:08
【问题描述】:

我有 2 个 XML。我正在尝试在第一个 XML 上运行 XSLT,并使用键在第二个 XML 中匹配数据。在对第二个 XML 执行 template-match 时,我无法从第一个 XML 的匹配节点中提取数据(不知道如何从那里提取任何数据)并将其填充到那里。以下是示例和预期输出。

第一个 XML-

<parent>
    <child>
        <name>John</name>
        <city>Boston</city>
        <shortCityCode>B</shortCityCode>
    </child>
    <child>
        <name>John</name>
        <city>Seattle</city>
        <shortCityCode>S</shortCityCode>
    </child>
    <child>
        <name>Allison</name>
        <city>Houston</city>
        <shortCityCode>H</shortCityCode>
    </child>
</parent>

第二个 XML - 在 XSLT 中作为变量内联

XSLT 尝试-

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="details">
<details>
    <parent>
        <detail>
            <city>Boston</city>
            <code>abc</code>
        </detail>
        <detail>
            <city>Houston</city>
            <code>xyz</code>
        </detail>
    </parent>
    <parent>
        <detail>
            <city>Boston</city>
            <code>abc</code>
        </detail>
        <detail>
            <city>Seattle</city>
            <code>mno</code>
        </detail>
    </parent>
    <parent>
        <detail>
            <city>Houston</city>
            <code>xyz</code>
        </detail>
        <detail>
            <city>Seattle</city>
            <code>mno</code>
        </detail>
    </parent>
</details>      
  </xsl:param>

  <xsl:key name="parent-ref" match="parent" use="detail/city"/>
  <xsl:key name="detail-ref" match="parent/detail" use="city"/>

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="parent">
    <FinalData>
        <xsl:for-each-group select="child" group-by="name">
            <Data>
                <xsl:copy-of select="name"/>
            </Data>
            <Details>
                <xsl:apply-templates select="key('parent-ref', current-group()/city, $details)"/>
            </Details>
        </xsl:for-each-group>
    </FinalData>
  </xsl:template>

  <xsl:template match="details/parent">
      <detail>
          <xsl:apply-templates select="key('detail-ref', current-group()/city, .)"/>
      </detail>
  </xsl:template>

  <xsl:template match="detail">
      <city value="{shortCityCode}"> //Here I want to populate the value from 1st XML
          <xsl:value-of select="code"/>
      </city>
  </xsl:template>
</xsl:stylesheet>

我需要提取 shortCityCode 字段并填充到上述 XSLT 的第二个模板调用中。下面是上面需要的 XSLT 的片段 -

  <xsl:template match="detail">
      <city value="{shortCityCode}"> //shortCityCode from 1st XML where key is matching the values.
          <xsl:value-of select="code"/>
      </city>
  </xsl:template>

预期输出 -

<FinalData>
    <Data>
        <name>John</name>
        <details>
            <detail>
                <city value="B">abc</city>
            </detail>
            <detail>
                <city value="B">abc</city>
                <city value="S">mno</city>
            </detail>
            <detail>
                <city value="S">mno</city>
            </detail>
        </details>
    </Data>
    <Data>
        <name>Allison</name>
        <details>
            <detail>
                <city value="H">xyz</city>
            </detail>
            <detail>
                <city value="H">xyz</city>
            </detail>
        </details>
    </Data>
</FinalData>

【问题讨论】:

  • 请一次问一个问题。将示例减少到演示问题所需的最低限度也会有所帮助。
  • @michael.hor257k 感谢您的建议,我已经用我的示例数据更新了问题,这更容易理解。

标签: xml xslt xslt-2.0 xslt-grouping xslt-3.0


【解决方案1】:

我认为您需要将模板更改为

  <xsl:template match="detail">
      <city value="{current-group()[city = current()/city]/shortCityCode}">
          <xsl:value-of select="code"/>
      </city>
  </xsl:template>

https://xsltfiddle.liberty-development.net/gVhDDyY/5

【讨论】:

  • 完美。谢谢你。只是想了解在模板与其他 XML 匹配后它是如何在这里引用的?
  • 在普通的 XSLT 2/3 中,current-group() 值即使在 for-each-group 之外也会保留,如果您处理其他节点(请参阅 w3.org/TR/xslt-30/#func-current-group “否则调用构造会保持当前组不变。在这种情况下,当前组的范围实际上是动态的:它可以在称为模板和属性集中的引用”)因此上面的建议只是利用了您之前使用的分组并且该组仍然存在。其余的是一个 XPath 谓词 [city = current()/city],用于将上下文所在的城市与组进行比较。
猜你喜欢
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 2020-12-22
  • 2015-01-07
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
相关资源
最近更新 更多