在 xslt1.0 中的每个节点中查找不同的值

Find distinct values across each node in xslt1.0

我想在每个节点中找到不同的值。但是当我使用 muenchian 方法时,它只会在顶层 select 不同的值。

目前我得到的输出为:

Bag 20
Tray 30

但我想对每件商品的类型和数量进行分组

<!--for 1st item-->
Bag 20
Tray 30
<!--for 2nd item-->
Bag 20
Box 20
Tray 30

我正在做一些研究让它工作但没有成功。

XML:

<?xml version="1.0" encoding="UTF-8"?>
<Test>
<Items>
    <Item>
        <name>A</name>
        <type>Bag</type>
        <input quantity="20"/>
       
    </Item>
    <Item>
        <name>A</name>
        <type>Bag</type>
        <input quantity="20"/>
     
    </Item>
    <Item>
        <name>B</name>
        <type>Metal</type>
        <input quantity="20"/>
       
    </Item>
    <Item>
        <name>A</name>
        <type>Tray</type>
        <input quantity="30"/>
     
    </Item>
    
</Items>
<Items>
    <Item>
        <name>A</name>
        <type>Bag</type>
        <input quantity="20"/>
       
    </Item>
    <Item>
        <name>A</name>
        <type>Box</type>
        <input quantity="20"/>
     
    </Item>
    <Item>
        <name>B</name>
        <type>Metal</type>
        <input quantity="20"/>
       
    </Item>
    <Item>
        <name>A</name>
        <type>Tray</type>
        <input quantity="30"/>
     
    </Item>
    
</Items>
</Test>

代码:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
   xmlns:date="http://exslt.org/dates-and-times"
    xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"
    extension-element-prefixes="date"
    
    >
    
    <xsl:key name="item-key" match="Items/Item[name='A']" use="input/@quantity" /> 
    
    <xsl:template match="/" name="Barcode">
        
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="ManufacturLabelSize-first" page-height="297mm" page-width="210mm"  margin-top="25.4mm" margin-right="25.4mm" margin-left="25.4mm" margin-bottom="25.4mm">
                    <fo:region-body margin-top="15mm" />
                    <fo:region-before />
                    <fo:region-after />
                </fo:simple-page-master>
                <fo:simple-page-master master-name="ManufacturLabelSize-rest" page-height="297mm" page-width="210mm"   margin-top="25.4mm" margin-right="25.4mm" margin-left="25.4mm" margin-bottom="25.4mm">
                    <fo:region-body margin-top="15mm"/>
                    <fo:region-before />
                    <fo:region-after />
                </fo:simple-page-master>
                <fo:page-sequence-master master-name="ManufacturLabelSize-portrait">
                    <fo:repeatable-page-master-alternatives>
                        <fo:conditional-page-master-reference master-reference="ManufacturLabelSize-first" 
                            page-position="first"/>
                        <fo:conditional-page-master-reference master-reference="ManufacturLabelSize-rest" 
                            page-position="rest"/>
                    </fo:repeatable-page-master-alternatives>
                </fo:page-sequence-master>
            </fo:layout-master-set>
            
            <fo:page-sequence master-reference="ManufacturLabelSize-portrait" id="pSeqID">
                
                <fo:flow flow-name="xsl-region-body">
                    
                    <fo:table  >
                        
                        <fo:table-body border="solid" border-width="0.5pt">
                            <fo:table-row>
                                <fo:table-cell>
                                    
                                    <fo:block>
                                        
                                        <xsl:for-each select="Test">
                                            <xsl:for-each select="Items">
                                               
                                                <xsl:for-each select="Item[name='A'][count(. | key('item-key',input/@quantity)[1])=1]">
                                               
                                                <fo:block>
                                                    <xsl:value-of select="type"/> <fo:inline color="white">XXX</fo:inline><xsl:value-of select="input/@quantity"/>
                                                    
                                                </fo:block>
                                             </xsl:for-each> 
                                         </xsl:for-each> 
                                         
                                        </xsl:for-each>
                                    </fo:block>
                                    
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-body>          
                    </fo:table> 
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
        
    </xsl:template> 
    
</xsl:stylesheet>

感谢您的帮助!

如果 - 看起来 - 你想找到不同的 Item,其 name 是 A 的 type 分别为每个 Items,那么你需要在密钥中包含父 Items' id。这是一个简化的示例:

XSLT 1.0

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

<xsl:key name="k" match="Item[name='A']" use="concat(type, '|', generate-id(..))"/>

<xsl:template match="/Test">
    <root>
        <xsl:for-each select="Items">
            <xsl:comment>
                <xsl:value-of select="position()" />
            </xsl:comment>
            <xsl:for-each select="Item[name='A'][count(. | key('k', concat(type, '|', generate-id(..)))[1]) = 1]">
                <item>
                    <type>
                        <xsl:value-of select="type"/>
                    </type>
                    <quantity>
                        <xsl:value-of select="input/@quantity"/>
                    </quantity>
                </item>
            </xsl:for-each>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <!--1-->
  <item>
    <type>Bag</type>
    <quantity>20</quantity>
  </item>
  <item>
    <type>Tray</type>
    <quantity>30</quantity>
  </item>
  <!--2-->
  <item>
    <type>Bag</type>
    <quantity>20</quantity>
  </item>
  <item>
    <type>Box</type>
    <quantity>20</quantity>
  </item>
  <item>
    <type>Tray</type>
    <quantity>30</quantity>
  </item>
</root>