基于 2 XMLs 创建 XML 并使用 XSLT2.0 在两个文件中查找值

Create XML based on 2 XMLs and looking up values in both files using XSLT2.0

我正在尝试根据另外 2 个 XML 生成一个 XML。我正在轮询一个 returns 人详细信息的数据库(查询中可以返回 n 人)。 最后的 XML 应该有 数据标签 的确切数量,因为 不同的名称标签 在 XML 来自 DB。例如:

1st XML- 从数据库中获取这个

<parent>
    <child>
        <name>John</name>
        <city>Boston</city>
    </child>
    <child>
        <name>John</name>
        <city>Seattle</city>
    </child>
    <child>
        <name>Allison</name>
        <city>Houston</city>
    </child>
</parent>

第 2 XML- 从其他来源获取

<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>

首先我需要创建 2 个数据标签,因为有 2 个不同的名字 - John 和 Allison(这部​​分已经完成并且 运行 很好)。 然后我需要检查 John,无论返回的数据库行中是否存在唯一的城市标签。让我们考虑第一个 XML,我们有与波士顿和西雅图有关的约翰。所以一个一个地,我将检查第二个 XML 中的那些城市,并且对于我匹配的每个 parent 标签,我将创建一个新标签 details 并粘贴所有相关内容。

1) 如果没有匹配的条目,则不应创建详细信息标签,因为没有匹配的条目。

2) city 标签将出现在 parent 标签下。 city 标签的值在 parent 标签中是唯一的。我必须在第二个 XML 中一个一个地匹配 city 并从所有匹配的 city 标签中获取值,跨越所有 parents 来自第二个 XML 并以 parent 标签中匹配的任何内容进入相应的 detail 输出中的标记 XML。 PFB 示例 XMLs,这将以更好的方式解释 -

最终预期 XML-

<FinalData>
    <Data>
        <name>John</name>
        <details>
            <detail>
                <city value="Boston">abc</city>
            </detail>
            <detail>
                <city value="Boston">abc</city>
                <city value="Seattle">mno</city>
            </detail>
            <detail>
                <city value="Seattle">mno</city>
            </detail>
        </details>
    </Data>
    <Data>
        <name>Allison</name>
        <details>
            <detail>
                <city value="Houston">xyz</city>
            </detail>
            <detail>
                <city value="Houston">xyz</city>
            </detail>
        </details>
    </Data>
</FinalData>

目前我的 XSLT 正在生成如下所示的结果 -

<FinalData>
    <Data>
        <name>John</name>
        <details>
            <detail>
                <city value="Boston">abc</city>
                <city value="Boston">abc</city>
                <city value="Seattle">mno</city>
                <city value="Seattle">mno</city>
            </detail>
        </details>
    </Data>
    <Data>
        <name>Allison</name>
        <details>
            <detail>
                <city value="Houston">xyz</city>
                <city value="Houston">xyz</city>
            </detail>
        </details>
    </Data>
</FinalData>

希望这是清楚的,因为我不擅长解释。

使用按键解析交叉引用:

<?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="{city}">
          <xsl:value-of select="code"/>
      </city>
  </xsl:template>

</xsl:stylesheet>

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

为了完整起见,第二个文档是内联的,但您当然可以使用 <xsl:param name="details" select="doc('details.xml')"/>