在XSLT中循环使用两个独立列表

时间:2017-08-22 13:57:23

标签: xml xslt-2.0 xslt-grouping

我的XML包含两个列表元素。在第一个循环上运行时,我需要在第一个循环中的第二个元素上运行循环。你能帮我解决吗?

以下是我的示例XML

  <?xml version="1.0" encoding="UTF-8"?>
    <Data>
       <Object>
          <ID>123</ID>
          <List>
             <ListItem>
                <ReferenceToObject>123</ReferenceToObject>
                <Name>ABC</Name>
             </ListItem>
             <ListItem>
                <ReferenceToObject>345</ReferenceToObject>
                <Name>CDE</Name>
             </ListItem>
             <ListItem>
                <ReferenceToObject>456</ReferenceToObject>
                <Name>EFG</Name>
             </ListItem>
          </List>
          <Line>
             <LineItem>
                <ReferenceToObject>123</ReferenceToObject>
                <LineName>ABCD</LineName>
             </LineItem>
             <LineItem>
                <ReferenceToObject>345</ReferenceToObject>
                <LineName>CDEF</LineName>
             </LineItem>
             <LineItem>
                <ReferenceToObject>456</ReferenceToObject>
                <LineName>EFGH</LineName>
             </LineItem>
          </Line>
       </Object>
    </Data>

While running on the first loop i would like to include the elements in the list list where in i can match it using ReferenceToObject.

The output i want is like below

<Data>
   <Object>
      <ID>123</ID>
      <List>
         <ListItem>
            <ReferenceToObject>123</ReferenceToObject>
            <Name>ABC</Name>
            <LineName>ABCD</LineName>
         </ListItem>
         <ListItem>
            <ReferenceToObject>345</ReferenceToObject>
            <Name>CDE</Name>
            <LineName>CDEF</LineName>
         </ListItem>
         <ListItem>
            <ReferenceToObject>456</ReferenceToObject>
            <Name>EFG</Name>
            <LineName>EFGH</LineName>
         </ListItem>
      </List>
</Object>
</Data>

我在该循环中的第一个元素上运行for循环我想为LineName运行另一个循环并复制匹配的referenceToObject字段。

问候

1 个答案:

答案 0 :(得分:0)

您可以使用for-each-group:

XSLT 2.0

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:template match="List">
            <xsl:copy>
                <xsl:for-each-group select="//ListItem|//LineItem" group-by="ReferenceToObject">
                    <ListItem>
                        <xsl:copy-of select="ReferenceToObject"/>
                        <xsl:copy-of select="current-group()/Name"/>
                        <xsl:copy-of select="current-group()/LineName"/>
                    </ListItem>
                </xsl:for-each-group>
            </xsl:copy>
        </xsl:template>

        <xsl:template match="Line"/>

 <!-- Identity Transformation -->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

XSLT 1.0 中使用密钥

处理此问题
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="refobject" match="LineItem" use="ReferenceToObject"/>

    <xsl:template match="List">
        <xsl:copy>
            <xsl:for-each select="ListItem">
                <xsl:copy>
                    <xsl:copy-of select="child::*"/>
                    <xsl:variable name="currentobj" select="normalize-space(ReferenceToObject)"/>
                    <xsl:copy-of select="key('refobject', $currentobj)/LineName"/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Line"/>

    <!-- Identity Transformation -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>