xslt distinct-values不适用于属性

时间:2016-06-02 05:34:03

标签: xslt

我有以下xml文件,我需要找出多个组中存在的不同属性语言数。

 <?xml version="1.0" encoding="UTF-8"?>
 <tns:DfCustomer>
<tns:Date_TimeList>
    <tns:Date_Time index="1">1404211736</tns:Date_Time>
</tns:Date_TimeList>
<tns:Short_NameList>
    <tns:Short_Name language="GB">ABC EUROPE</tns:Short_Name>
</tns:Short_NameList>
<tns:Name_1List>
    <tns:Name_1 language="GB">ABC EUROPE</tns:Name_1>
</tns:Name_1List>
<tns:Name_2List>
    <tns:Name_2 language="GB">ABC EUROPE</tns:Name_2>
</tns:Name_2List>
<tns:StreetList>
    <tns:Street language="GB">FRANKFURTER STR.107</tns:Street>
    <tns:Street language="FR">D-64807 DIEBURG</tns:Street>
</tns:StreetList>
<tns:address1List>
    <tns:address1 language="GB" index="1">Test GB Address 1</tns:address1>
    <tns:address1 language="FR" index="1">Test FR Address 1</tns:address1>
    <tns:address1 language="DE" index="1">Test DE Address 1</tns:address1>
    <tns:address1 language="GB" index="2">Test GB Address 2</tns:address1>
    <tns:address1 language="FR" index="2">Test FR Address 2</tns:address1>
    <tns:address1 language="GB" index="3">Test GB Address 3</tns:address1>
</tns:address1List>
<tns:Town_CountryList>
    <tns:Town_Country language="GB">GERMANY</tns:Town_Country>
</tns:Town_CountryList>

在上面的例子中,我有3种不同的语言,如GB,DE和FR。我希望得到计数3.我尝试遵循xslt / xpath函数,但似乎没有任何工作。在for-each循环中迭代时,它会产生堆栈溢出错误

1

<xsl:value-of select="count(distinct-values(dfns:*/dfns:*[@language]/@language))" />

2

<xsl:variable name="total">
    <xsl:for-each select="dfns:*/dfns:*[@language]/@language">
                    <xsl:value-of select="."/>
                </xsl:for-each>

3

<xsl:variable name="total">
    <xsl:for-each-group select="dfns:*/dfns:*[@language]" group-by="@language">
                <xsl:value-of select="."/>
            </xsl:for-each-group>
  1. 尝试使用的generate-id和generate-key()函数也无法正常工作..
  2. 我不确定我做错了什么。请帮我。

2 个答案:

答案 0 :(得分:0)

给出一个格式良好的输入,例如:

<强> XML

<root>
   <Date_TimeList>
      <Date_Time index="1">1404211736</Date_Time>
   </Date_TimeList>
   <Short_NameList>
      <Short_Name language="GB">ABC EUROPE</Short_Name>
   </Short_NameList>
   <Name_1List>
      <Name_1 language="GB">ABC EUROPE</Name_1>
   </Name_1List>
   <Name_2List>
      <Name_2 language="GB">ABC EUROPE</Name_2>
   </Name_2List>
   <StreetList>
      <Street language="GB">FRANKFURTER STR.107</Street>
      <Street language="FR">D-64807 DIEBURG</Street>
   </StreetList>
   <address1List>
      <address1 language="GB" index="1">Test GB Address 1</address1>
      <address1 language="FR" index="1">Test FR Address 1</address1>
      <address1 language="DE" index="1">Test DE Address 1</address1>
      <address1 language="GB" index="2">Test GB Address 2</address1>
      <address1 language="FR" index="2">Test FR Address 2</address1>
      <address1 language="GB" index="3">Test GB Address 3</address1>
   </address1List>
   <Town_CountryList>
      <Town_Country language="GB">GERMANY</Town_Country>
   </Town_CountryList>
</root>

以下样式表:

XSLT 2.0

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

<xsl:template match="/">
    <result>
        <xsl:value-of select="count(distinct-values(//@language))" />
    </result>
</xsl:template>

</xsl:stylesheet>

将返回:

<?xml version="1.0" encoding="UTF-8"?>
<result>3</result>

答案 1 :(得分:0)

因为Nodepad ++ XML Tools基于libxml,它只支持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="klanguage" match="*[@language]" use="@language"/>


  <xsl:template match="/*">
    <xsl:copy>
      <xsl:value-of select="count( //*[
        generate-id()
        = 
        generate-id(key('klanguage', @language)[1])
      ])" />

    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

使用notepad ++生成以下输出:

 <?xml version="1.0" encoding="UTF-8"?>
 <root>3</root>

基于:https://stackoverflow.com/a/1590316/2115381