C# xslt中xml数据的过滤和分组
我有一个xml内容,我正在应用XSLT1.0进行转换。我还传递过滤参数。但我无法在XSLT1.0中对过滤后的数据进行分组 我将传递“国家值”(如“美国”)作为过滤参数。过滤后,分组将应用于过滤数据的“组”字段。如果只存在一个组,则不要对数据进行分组。仅当可能有多个组时才应用分组 请帮我做这个 提前谢谢 下面是我的示例XML内容C# xslt中xml数据的过滤和分组,c#,xml,xslt,C#,Xml,Xslt,我有一个xml内容,我正在应用XSLT1.0进行转换。我还传递过滤参数。但我无法在XSLT1.0中对过滤后的数据进行分组 我将传递“国家值”(如“美国”)作为过滤参数。过滤后,分组将应用于过滤数据的“组”字段。如果只存在一个组,则不要对数据进行分组。仅当可能有多个组时才应用分组 请帮我做这个 提前谢谢 下面是我的示例XML内容 <?xml version="1.0" encoding="utf-8" ?> <DataRows> -<DataRow>
<?xml version="1.0" encoding="utf-8" ?>
<DataRows>
-<DataRow>
- <Country>
<Conty>United States</Conty>
<Conty>United Kingdom</Conty>
</Country>
<Group>Group 1</Group>
<Order>1</Order>
<Name>Name 1_1</Name>
<Title>Title 1</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
<Conty>United Kingdom</Conty>
</Country>
<Group>Group 1</Group>
<Order>2</Order>
<Name>Name 2_2</Name>
<Title>Title 2</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
</Country>
<Group>Group 1</Group>
<Order>1</Order>
<Name>Name 3_1</Name>
<Title>Title 3</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
<Conty>Germany</Conty>
</Country>
<Group>Group 1</Group>
<Order>2</Order>
<Name>Name 4_2</Name>
<Title>Title 4</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
</Country>
<Group>Group 2</Group>
<Order>4</Order>
<Name>Name 8_4</Name>
<Title>Title 8</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United Kingdom</Conty>
</Country>
<Group>Group 2</Group>
<Order>1</Order>
<Name>Name 9_1</Name>
<Title>Title 9</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
<Conty>Germany</Conty>
</Country>
<Group>Group 2</Group>
<Order>3</Order>
<Name>Name 5_3</Name>
<Title>Title 5</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
<Conty>Germany</Conty>
</Country>
<Group>Group 2</Group>
<Order>4</Order>
<Name>Name 6_4</Name>
<Title>Title 6</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>United States</Conty>
</Country>
<Group>Group 2</Group>
<Order>3</Order>
<Name>Name 7_3</Name>
<Title>Title 7</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
-<DataRow>
- <Country>
<Conty>Germany</Conty>
</Country>
<Group>Group 1</Group>
<Order>1</Order>
<Name>Name 10_1</Name>
<Title>Title 10</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl />
<EmailId />
</DataRow>
</DataRows>
-
-
美国
大不列颠联合王国
第一组
1.
姓名1_1
标题1
732-989-9898
-
-
美国
大不列颠联合王国
第一组
2.
名称2_2
标题2
732-989-9898
-
-
美国
第一组
1.
姓名3_1
标题3
732-989-9898
-
-
美国
德国
第一组
2.
名称4_2
标题4
732-989-9898
-
-
美国
第2组
4.
姓名8_4
标题8
732-989-9898
-
-
大不列颠联合王国
第2组
1.
姓名9_1
标题9
732-989-9898
-
-
美国
德国
第2组
3.
姓名5_3
标题5
732-989-9898
-
-
美国
德国
第2组
4.
姓名6_4
标题6
732-989-9898
-
-
美国
第2组
3.
姓名7_3
标题7
732-989-9898
-
-
德国
第一组
1.
姓名10_1
标题10
732-989-9898
除非您进行了两阶段转换,否则我认为您可能应该首先进行分组,然后进行过滤
分组将通过通用的Meunchain分组方法实现。首先定义一个键,以便根据组查找数据行元素
<xsl:key name="RowLookup" match="DataRow" use="Group"/>
然后,为了获得唯一的组名,需要匹配DataRow元素,这些元素恰好是其特定组的键中第一个出现的元素
<xsl:apply-templates select="DataRow[generate-id() = generate-id(key('RowLookup', Group)[1])]"/>
因此,现在您已经按照组元素进行分组,因此您需要在那里检查至少一个与筛选器匹配的当前组的DataRow元素
<xsl:if test="../DataRow[Group=current()/Group]/Country[Conty=$Conty]">
然后,要获取当前组的所有DataRow元素,可以使用键
<xsl:apply-templates select="key('RowLookup', Group)" mode="ingroup"/>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="Conty">United Kingdom</xsl:param>
<xsl:key name="RowLookup" match="DataRow" use="Group"/>
<xsl:template match="/DataRows">
<xsl:copy>
<!-- Select unique groups -->
<xsl:apply-templates
select="DataRow[generate-id() = generate-id(key('RowLookup', Group)[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DataRow">
<!-- Check any DataRow elements for the current group match the filter -->
<xsl:if test="../DataRow[Group=current()/Group]/Country[Conty=$Conty]">
<Group>
<xsl:attribute name="name">
<xsl:value-of select="Group"/>
</xsl:attribute>
<!-- Get all the DataRow elements for the current group -->
<xsl:apply-templates select="key('RowLookup', Group)" mode="ingroup"/>
</Group>
</xsl:if>
</xsl:template>
<xsl:template match="DataRow" mode="ingroup">
<!-- Check this DataRow matches the filter -->
<xsl:if test="Country[Conty=$Conty]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Ignore Group and Country elements -->
<xsl:template match="Group|Country"/>
<!-- Standard Identity Transform for all other nodes -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
大不列颠联合王国
将此XSLT应用于示例XML时,会得到以下结果
<DataRows>
<Group name="Group 1">
<DataRow>
<Order>1</Order>
<Name>Name 1_1</Name>
<Title>Title 1</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
<DataRow>
<Order>2</Order>
<Name>Name 2_2</Name>
<Title>Title 2</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
<Group name="Group 2">
<DataRow>
<Order>1</Order>
<Name>Name 9_1</Name>
<Title>Title 9</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
</DataRows>
1.
姓名1_1
标题1
732-989-9898
2.
名称2_2
标题2
732-989-9898
1.
姓名9_1
标题9
732-989-9898
我不确定这是否是您想要的确切结构,但我希望它能为您提供总体思路。如果您真的想先进行过滤,然后进行分组,那么您将看到某种“两次”转换。这可以通过使用节点集扩展函数来实现,以创建包含过滤数据的结果树片段 在下面的示例中,我正在使用Microsoft的扩展功能,但根据您的平台,您可能需要指定另一个扩展功能。(EXSLT是另一种常见的方法。请使用名称空间。)
大不列颠联合王国
使用此选项时,输出应如下所示
<DataRows>
<Group name="Group 1">
<DataRow>
<Order>1</Order>
<Name>Name 1_1</Name>
<Title>Title 1</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
<DataRow>
<Order>2</Order>
<Name>Name 2_2</Name>
<Title>Title 2</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
<Group name="Group 2">
<DataRow>
<Order>1</Order>
<Name>Name 9_1</Name>
<Title>Title 9</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
</DataRows>
1.
姓名1_1
标题1
732-989-9898
2.
名称2_2
标题2
732-989-9898
1.
姓名9_1
标题9
732-989-9898
有关更多信息,请参阅。非常感谢Tim的回复,并花时间研究这个问题。很抱歉,您提供给我的xslt都不起作用。如果你能给我一些解决方案,先做过滤,然后分组,这将是伟大的,但如果不可能,你会给我的解决方案,将做分组,然后过滤,这也将是伟大的。这对我工作!当你尝试的时候,你能更精确地描述一下发生在你身上的事情吗?你有错误吗?输出XML是否不符合预期?如果你能提供一个你所期望的输出的例子,那会有很大帮助。对不起,蒂姆,这是我的错,你的xslt部分工作得很好。事实上,我还有一些其他的东西和你给我的东西,我在把你的xslt和我的xslt集成在一起时犯了一个小错误。但我会保持您的部分不变,并稍微调整一下xslt及其工作方式。但我还是试着先过滤,然后分组,如果只有一个组,就不要分组项目。若我通过了过滤器值,并基于它,若只有一个组是可能的,那个么就并没有了
<DataRows>
<Group name="Group 1">
<DataRow>
<Order>1</Order>
<Name>Name 1_1</Name>
<Title>Title 1</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
<DataRow>
<Order>2</Order>
<Name>Name 2_2</Name>
<Title>Title 2</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
<Group name="Group 2">
<DataRow>
<Order>1</Order>
<Name>Name 9_1</Name>
<Title>Title 9</Title>
<PhoneNo>732-989-9898</PhoneNo>
<ImageUrl/>
<EmailId/>
</DataRow>
</Group>
</DataRows>