简体   繁体   English

具有嵌套值的XSLT 1.0多重分组

[英]XSLT 1.0 Mutliple Grouping with nested values

I am trying to transform XML into another XML file but I am unsuccessfully selecting the values to be contained in each group. 我正在尝试将XML转换为另一个XML文件,但未成功选择要包含在每个组中的值。

I have tried the Muenchian method, but this discards the values I want to retain for the next level of grouping. 我已经尝试了Muenchian方法,但这会丢弃我要保留用于下一级别分组的值。

Input XML 输入XML

<?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
    <GUID>
        <PolicyNumber>P0001</PolicyNumber>
        <CoverElement>Buildings</CoverElement>
        <LocationID>1</LocationID>
    </GUID>
    <GUID>
        <PolicyNumber>P0002</PolicyNumber>
        <CoverElement>Buildings</CoverElement>
        <LocationID>1</LocationID>
        </GUID>
    <GUID>
        <PolicyNumber>P0002</PolicyNumber>
        <CoverElement>Contents</CoverElement>
        <LocationID>1</LocationID>
    </GUID>
    <GUID>
        <PolicyNumber>P0002</PolicyNumber>
        <CoverElement>Contents</CoverElement>
        <LocationID>2</LocationID>
    </GUID>
    <GUID>
        <PolicyNumber>P0002</PolicyNumber>
        <CoverElement>Liability</CoverElement>
        <LocationID>1</LocationID>
    </GUID>
    <GUID>
        <PolicyNumber>P0002</PolicyNumber>
        <CoverElement>Liability</CoverElement>
        <LocationID>2</LocationID>
    </GUID>
</NewDataSet>

My XSLT attempt 我的XSLT尝试

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="TestKey" match="NewDataSet/GUID/PolicyNumber" use="." />

    <xsl:template match="/">
        <xsl:for-each select="NewDataSet">
            <InputXML>
                <xsl:for-each select="GUID/PolicyNumber[generate-id() = generate-id(key('TestKey', .)[1])]">
                    <PolicyData>
                        <xsl:variable name="currentGroup" select="."/>
                            <PolicyNumber><xsl:value-of select="$currentGroup" /></PolicyNumber>
                                <xsl:for-each select="key('TestKey', $currentGroup)">
                                    <LocationData>
                                        <LocationID><xsl:value-of select="../LocationID"/></LocationID>
                                            <CoverData>
                                                <CoverElement><xsl:value-of select="../CoverElement"/></CoverElement>
                                            </CoverData>
                                    </LocationData> 
                                 </xsl:for-each>
                    </PolicyData>
                </xsl:for-each>
            </InputXML>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

The result 结果

    <?xml version="1.0" encoding="UTF-8"?>
<InputXML>
   <PolicyData>
      <PolicyNumber>P0001</PolicyNumber>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Buildings</CoverElement>
         </CoverData>
      </LocationData>
   </PolicyData>
   <PolicyData>
      <PolicyNumber>P0002</PolicyNumber>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Buildings</CoverElement>
         </CoverData>
      </LocationData>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Contents</CoverElement>
         </CoverData>
      </LocationData>
      <LocationData>
         <LocationID>2</LocationID>
         <CoverData>
            <CoverElement>Contents</CoverElement>
         </CoverData>
      </LocationData>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Liability</CoverElement>
         </CoverData>
      </LocationData>
      <LocationData>
         <LocationID>2</LocationID>
         <CoverData>
            <CoverElement>Liability</CoverElement>
         </CoverData>
      </LocationData>
   </PolicyData>
</InputXML>

Trying to achieve 试图实现

    <?xml version="1.0" encoding="UTF-8"?>
<InputXML>
   <PolicyData>
      <PolicyNumber>P0001</PolicyNumber>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Buildings</CoverElement>
         </CoverData>
      </LocationData>
   </PolicyData>
   <PolicyData>
      <PolicyNumber>P0002</PolicyNumber>
      <LocationData>
         <LocationID>1</LocationID>
         <CoverData>
            <CoverElement>Buildings</CoverElement>
         </CoverData>
         <CoverData>
            <CoverElement>Contents</CoverElement>
         </CoverData>
         <CoverData>
            <CoverElement>Liability</CoverElement>
         </CoverData>            
      </LocationData>
      <LocationData>
         <LocationID>2</LocationID>
         <CoverData>
            <CoverElement>Contents</CoverElement>
         </CoverData>
         <CoverData>
            <CoverElement>Liability</CoverElement>
         </CoverData>
      </LocationData>
   </PolicyData>
</InputXML>

Any help would be appreciated. 任何帮助,将不胜感激。

You need to define three keys, where the key for the next level includes the value of the key for the previous level: 您需要定义三个键,其中下一级的键包括上一级的键的值:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output indent="yes"/>

    <xsl:key name="pn" match="GUID" use="PolicyNumber"/>
    <xsl:key name="loc" match="GUID" use="concat(PolicyNumber, '|', LocationID)"/>
    <xsl:key name="cov" match="GUID" use="concat(PolicyNumber, '|', LocationID, '|', CoverElement)"/>

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

    <xsl:template match="NewDataSet">
        <InputXML>
            <xsl:apply-templates select="GUID[generate-id() = generate-id(key('pn', PolicyNumber)[1])]"/>
        </InputXML>
    </xsl:template>

    <xsl:template match="GUID">
        <PolicyData>
            <xsl:copy-of select="PolicyNumber"/>
            <xsl:apply-templates select="key('pn', PolicyNumber)[generate-id() = generate-id(key('loc', concat(PolicyNumber, '|', LocationID))[1])]" mode="loc">
                <xsl:sort select="LocationID" data-type="number"/>
            </xsl:apply-templates>
        </PolicyData>
    </xsl:template>

    <xsl:template match="GUID" mode="loc">
        <LocationData>
            <xsl:copy-of select="LocationID"/>
            <xsl:apply-templates select="key('loc', concat(PolicyNumber, '|', LocationID))[generate-id() = generate-id(key('cov', concat(PolicyNumber, '|', LocationID, '|', CoverElement))[1])]" mode="cov">
                <xsl:sort select="CoverElement"/>
            </xsl:apply-templates>
        </LocationData>
    </xsl:template>

    <xsl:template match="GUID" mode="cov">
        <CoverData>
            <xsl:copy-of select="CoverElement"/>
        </CoverData>
    </xsl:template>

</xsl:transform>

Online at http://xsltransform.net/bnnZWy . 在线http://xsltransform.net/bnnZWy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM