【问题标题】:XSLT how to display/output duplicate values based on different element node and attributesXSLT如何根据不同的元素节点和属性显示/输出重复值
【发布时间】:2020-01-31 04:41:29
【问题描述】:

我正在尝试使用 XSLT 跨不同节点和值输出重复值。我希望节点元素是动态的,以便它可以在命名空间前缀之后跟踪不同的值,例如:car:ID、car:Name、car:Location_name 或更多。我知道我可以使用函数 Local-Name(.) 但我不确定如何应用于我的 XSLT 逻辑。请帮忙 示例 XML 如下:

<car:root xmlns:car="com.sample">
<Car_Input_Request>
    <car:Car_Details>
        <car:ID>Car_001</car:ID>
        <car:Name>Fastmobile</car:Name>
        <car:Local_Name>New York</car:Local_Name>
        <car:Transmission_Reference_Type>
            <car:ID car:type="Transmission_Reference_Type">Automatic</car:ID>
        </car:Transmission_Reference_Type>
    </car:Car_Details>      
</Car_Input_Request>
    <Car_Input_Request>
        <car:Car_Details>
            <car:ID>Car_002</car:ID>
            <car:Name>Slowmobile</car:Name>
            <car:Local_Name>New York</car:Local_Name>
            <car:Transmission_Reference_Type>
                <car:ID car:type="Transmission_Reference_Type">Manual</car:ID>
            </car:Transmission_Reference_Type>
        </car:Car_Details>      
    </Car_Input_Request>
    <Car_Input_Request>
        <car:Car_Details>
            <car:ID>Car_001</car:ID>
            <car:Name>Fastmobile</car:Name>
            <car:Local_Name>New York</car:Local_Name>
            <car:Transmission_Reference_Type>
                <car:ID car:type="Transmission_Reference_Type">Automatic</car:ID>
            </car:Transmission_Reference_Type>
        </car:Car_Details>      
    </Car_Input_Request>
</car:root>

使用的 XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:car="com.sample"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:value-of select="//car:ID[ let $v:=string(.),$t:=@car:type return not( preceding::car:ID[string(.) = $v and @car:type=$t]) ]/(let $v:=string(.), $t:=@car:type,$c:=1+count(following::car:ID[string(.)=$v and $t=@car:type]) ,$c:=1+count(following::car:*[string(.)=$v]) return if ($c > 1) then concat( string(.), ' occurs ', $c, ' times for type ', $t, '&#13;&#10;') else () )"/>
    </xsl:template>
</xsl:stylesheet>

xslt 显示的输出:

Car_001 occurs 2 times for type 
 Automatic occurs 2 times for type Transmission_Reference_Type

但我想让它显示出来

Car_001 occurs 2 times for type ID
Fastmobile occurs 2 times for type Name
Automatic occurs 2 times for type Transmission_Reference_Type
New York occurs 3 times for type Local_Name

【问题讨论】:

  • 第一行 //car:ID[ let $v:=string(.),$t:=@car:type return not( preceding::car:ID[string(.) = $v and @car:type=$t]) ] 查找所有不具有 dup 值的 car:ID 元素。然后/(let $v:=string(.), $t:=@car:type,$c:=1+count(following::car:ID[string(.)=$v and $t=@car:type]) ,$c:=1+count(following::car:*[string(.)=$v]) return if ($c &gt; 1) then concat( string(.), ' occurs ', $c, ' times for type ', $t, '&amp;#13;&amp;#10;') else () )显示重复值,如果计数大于1,并输出变量值如$t,$c等。
  • 对于在序列中查找所有重复值的单个 XPath 表达式,请参阅:stackoverflow.com/questions/133092/…

标签: ruby xml xslt nokogiri oxygenxml


【解决方案1】:

如果您正在寻找 XSLT 解决方案(而不是单行 XPath 表达式),您可以使用带有复合键的 xsl:for-each-group

<xsl:stylesheet
    xmlns:car="com.sample"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    expand-text="yes"
    version="3.0">

    <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:for-each-group select="//car:Car_Details/*" group-by="local-name(), normalize-space()" composite="yes">
        <xsl:if test="current-group()[2]">
          <xsl:text>{normalize-space()} occurs {count(current-group())} times for {local-name()}&#10;</xsl:text>
        </xsl:if>
      </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

  • 谢谢蒂姆,这就像一个魅力!另一个问题,你知道我怎样才能使每个组的选择动态化吗?如果我们有一个新的 API 请求是 car:Seller_Details 怎么办?或汽车:Buyer_Details...我们可以做select="car:*[....]吗?
  • 例如,您可以使用select="//car:*[count(ancestor::car:*) = 1]/*" 来避免选择car:rootcar:Car_Details 的子代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多