0

我正在尝试基于其他 2 个 XML 生成 XML。我正在轮询一个返回人员详细信息的数据库(查询中可以返回 n 人)。最终的 XML 应该具有与来自 DB 的 XML 中不同的名称标签相同数量的Data 标签。例如:

第一个 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>

第二个 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,无论返回的 DB 行中是否存在唯一的城市标签。让我们考虑第一个 XML,我们有与波士顿和西雅图有关的 John。因此,我将一一检查第二个 XML 中的这些城市,并且对于我匹配的每个标记,我将创建一个新的标记详细信息并粘贴所有相关内容。

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

2)城市标签将在标签下。城市标签的值在标签中是唯一的。我必须在第二个 XML 中一一匹配城市,并从第二个 XML 的所有父级中的所有匹配城市标记中获取值,以父标记中匹配的任何内容进入输出XML中的相应详细信息标记的方式进行填充. PFB 示例 XML,可以更好地解释 -

最终预期的 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>

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

4

1 回答 1

0

使用键来解决交叉引用:

<?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')"/>

于 2020-04-29T14:22:49.920 回答