我需要根据需要转换为所需的输出。
这是我的输入XML:
<ns0:SegmentationResponse xmlns:ns0 = "http://asdf.com/BTS/BusinessDashboard/SegmentationResponse/2013/08">
<Segmentation>
<segmentationName>PRODUCTION</segmentationName>
<SegmentationSubType>
<segmentationSubTypeName>Advisors</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<slno>1</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>sanga</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>sanga</name>
<value>0</value>
</ValueList>
</Value>
</SegmentationSubType>
<SegmentationSubType>
<segmentationSubTypeName>Accounts</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<slno>1</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>393</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>399</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>400</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>401</slno>
<name>2013090436647677</name>
<value>65</value>
</ValueList>
<ValueList>
<slno>402</slno>
<name>2013090436647677</name>
<value>65</value>
</ValueList>
<ValueList>
<slno>499</slno>
<name>2013090436663871</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>500</slno>
<name>2013090436663871</name>
<value>1</value>
</ValueList>
<ValueList>
<slno>501</slno>
<name>2013090436663871</name>
<value>1</value>
</ValueList>
</Value>
</SegmentationSubType>
</Segmentation>
</ns0:SegmentationResponse>
我想要输出如下(删除重复的名称并计算重复项并动态生成元素)。
<ns0:SegmentationResponse xmlns:ns0="http://asdf.com/BTS/BusinessDashboard/SegmentationResponse/2013/08">
<Segmentation>
<segmentationName>PRODUCTION</segmentationName>
<SegmentationSubType>
<segmentationSubTypeName>Advisors</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<name>JOSE CRUZ</name>
<value>3</value>
</ValueList>
<ValueList>
<name>sanga</name>
<value>2</value>
</ValueList>
</Value>
</SegmentationSubType>
<SegmentationSubType>
<segmentationSubTypeName>Accounts</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<name>2013090436641882</name>
<value>3</value>
</ValueList>
<ValueList>
<name>2013090436647677</name>
<value>2</value>
</ValueList>
<ValueList>
<name>2013090436663871</name>
<value>3</value>
</ValueList>
</Value>
</SegmentationSubType>
</Segmentation>
</ns0:SegmentationResponse>
这是我的xsl,它计算所有元素。但它需要按照上面的示例xml中的规定进行分组。任何人都可以提供帮助吗?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://asdf.com/BTS/BusinessDashboard/SegmentationResponse/2013/08">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="ns0:SegmentationResponse/Segmentation/SegmentationSubType">
<xsl:element name="segmentationSubTypeName">
<xsl:call-template name="calculate">
<xsl:with-param name="namecount" select="count(./Value/ValueList)"/>
<xsl:with-param name="name" select="./Value/ValueList/name"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="calculate">
<xsl:param name="namecount"/>
<xsl:param name="name"/>
<xsl:element name="Value">
<xsl:element name="ValueList">
<xsl:element name="name">
<xsl:value-of select="$name"/>
</xsl:element>
<xsl:element name="Value">
<xsl:value-of select="$namecount"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
以下是使用xsl:key
的一个选项(此处的工作示例:http://xsltransform.net/ncdD7mw/1)...
XML输入
<ns0:SegmentationResponse xmlns:ns0="http://asdf.com/BTS/BusinessDashboard/SegmentationResponse/2013/08">
<Segmentation>
<segmentationName>PRODUCTION</segmentationName>
<SegmentationSubType>
<segmentationSubTypeName>Advisors</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<slno>1</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>JOSE CRUZ</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>sanga</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>sanga</name>
<value>0</value>
</ValueList>
</Value>
</SegmentationSubType>
<SegmentationSubType>
<segmentationSubTypeName>Accounts</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<slno>1</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>2</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>3</slno>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<slno>393</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>399</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>400</slno>
<name>2013090436641882</name>
<value>7</value>
</ValueList>
<ValueList>
<slno>401</slno>
<name>2013090436647677</name>
<value>65</value>
</ValueList>
<ValueList>
<slno>402</slno>
<name>2013090436647677</name>
<value>65</value>
</ValueList>
<ValueList>
<slno>499</slno>
<name>2013090436663871</name>
<value>0</value>
</ValueList>
<ValueList>
<slno>500</slno>
<name>2013090436663871</name>
<value>1</value>
</ValueList>
<ValueList>
<slno>501</slno>
<name>2013090436663871</name>
<value>1</value>
</ValueList>
</Value>
</SegmentationSubType>
</Segmentation>
</ns0:SegmentationResponse>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!--Create key based on segmentation sub type and name.-->
<xsl:key name="valsBySubtype" match="ValueList" use="name"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Value">
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::ValueList)]|
ValueList[count(.|key('valsBySubtype',name)[1])=1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ValueList">
<xsl:copy>
<xsl:apply-templates select="@*|name|value"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ValueList/value">
<value>
<xsl:value-of select="count(key('valsBySubtype',../name))"/>
</value>
</xsl:template>
</xsl:stylesheet>
XML输出
<ns0:SegmentationResponse xmlns:ns0="http://asdf.com/BTS/BusinessDashboard/SegmentationResponse/2013/08">
<Segmentation>
<segmentationName>PRODUCTION</segmentationName>
<SegmentationSubType>
<segmentationSubTypeName>Advisors</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<name>JOSE CRUZ</name>
<value>3</value>
</ValueList>
<ValueList>
<name>sanga</name>
<value>2</value>
</ValueList>
</Value>
</SegmentationSubType>
<SegmentationSubType>
<segmentationSubTypeName>Accounts</segmentationSubTypeName>
<Value>
<valueTypeName/>
<ValueList>
<name>sure</name>
<value>3</value>
</ValueList>
<ValueList>
<name>2013090436641882</name>
<value>3</value>
</ValueList>
<ValueList>
<name>2013090436647677</name>
<value>2</value>
</ValueList>
<ValueList>
<name>2013090436663871</name>
<value>3</value>
</ValueList>
</Value>
</SegmentationSubType>
</Segmentation>
</ns0:SegmentationResponse>
如果你能够使用XSLT 2.0,那么这是另一个选择...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Value">
<xsl:copy>
<xsl:apply-templates select="@*|node() except ValueList"/>
<xsl:for-each-group select="ValueList" group-by="name">
<ValueList>
<name><xsl:value-of select="current-grouping-key()"/></name>
<value><xsl:value-of select="count(current-group())"/></value>
</ValueList>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>