在 XSL 中,执行类似于 C# 中的操作:list.Select(x=>x.ID).Distinct();

发布于 2024-10-07 12:50:27 字数 377 浏览 4 评论 0原文

我的目的是在 XSL 中,仅显示具有公共值的节点集的文本节点。例如,我有以下 XML:

<Nodes>
    <Node att="1">A</Node>
    <Node att="1">B</Node>
    <Node att="2">C</Node>
    <Node att="2">D</Node>
    <Node att="3">E</Node>
</Nodes>

我的输出将是:“ACE”。

我不知道属性“att”的值是什么。它可以是任何字符串。

任何建议将不胜感激!

My intent is in an XSL, to display only once the text node for set of nodes with a common value. For example, I have the following XML:

<Nodes>
    <Node att="1">A</Node>
    <Node att="1">B</Node>
    <Node att="2">C</Node>
    <Node att="2">D</Node>
    <Node att="3">E</Node>
</Nodes>

My output would be: "ACE".

I don't know what the values of the attribute "att" will be. It can be any string.

Any suggestion would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

快乐很简单 2024-10-14 12:50:27

这甚至可以在单个 XPath 表达式中完成

/*/*[not(@att=preceding-sibling::*/@att)]/text()

因此,将其包装在 XSLT 中为我们提供了

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:copy-of select="/*/*[not(@att=preceding-sibling::*/@att)]/text()"/>
 </xsl:template>
</xsl:stylesheet>

并将其应用到提供的 XML 文档: >

<Nodes>
    <Node att="1">A</Node>
    <Node att="1">B</Node>
    <Node att="2">C</Node>
    <Node att="2">D</Node>
    <Node att="3">E</Node>
</Nodes>

产生想要的正确结果

ACE

This can even be done just in a single XPath expression:

/*/*[not(@att=preceding-sibling::*/@att)]/text()

So, wrapping it in XSLT gives us:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:copy-of select="/*/*[not(@att=preceding-sibling::*/@att)]/text()"/>
 </xsl:template>
</xsl:stylesheet>

and applying this to the provided XML document:

<Nodes>
    <Node att="1">A</Node>
    <Node att="1">B</Node>
    <Node att="2">C</Node>
    <Node att="2">D</Node>
    <Node att="3">E</Node>
</Nodes>

produces the wanted, correct result:

ACE
潦草背影 2024-10-14 12:50:27

这是一个常见问题解答。请参阅http://www.jenitennison.com/xslt/grouping/muenchian.html

此 XSLT 代码:

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

<xsl:key name="criteria" match="/Nodes/Node" use="@att"/>

<xsl:template match="Nodes">   
    <xsl:copy>
        <xsl:apply-templates select="Node[generate-id() = generate-id(key('criteria', @att))]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Node">
    <xsl:copy-of select="."/> <!-- Or other actions -->
</xsl:template>

</xsl:stylesheet>

将提供所需的(如果我理解正确的话)输出:

<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
   <Node att="1">A</Node>
   <Node att="2">C</Node>
   <Node att="3">E</Node>
</Nodes>

它也可以与输入一起使用,例如:

<Nodes>
    <Node att="someRandomString">A</Node>
    <Node att="1aeawe">B</Node>
    <Node att="someRandomString">C</Node>
    <Node att="sfdf">D</Node>
    <Node att="">E</Node>
    <Node att="sfdf">F</Node>
</Nodes>

输出将是:

<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
    <Node att="someRandomString">A</Node>
    <Node att="1aeawe">B</Node>
    <Node att="sfdf">D</Node>
    <Node att="">E</Node>
</Nodes>

It's a FAQ. See http://www.jenitennison.com/xslt/grouping/muenchian.html

This XSLT code:

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

<xsl:key name="criteria" match="/Nodes/Node" use="@att"/>

<xsl:template match="Nodes">   
    <xsl:copy>
        <xsl:apply-templates select="Node[generate-id() = generate-id(key('criteria', @att))]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Node">
    <xsl:copy-of select="."/> <!-- Or other actions -->
</xsl:template>

</xsl:stylesheet>

Will provide the desired (if I understood correctly) output:

<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
   <Node att="1">A</Node>
   <Node att="2">C</Node>
   <Node att="3">E</Node>
</Nodes>

It would also work with input like, for example:

<Nodes>
    <Node att="someRandomString">A</Node>
    <Node att="1aeawe">B</Node>
    <Node att="someRandomString">C</Node>
    <Node att="sfdf">D</Node>
    <Node att="">E</Node>
    <Node att="sfdf">F</Node>
</Nodes>

Output will be:

<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
    <Node att="someRandomString">A</Node>
    <Node att="1aeawe">B</Node>
    <Node att="sfdf">D</Node>
    <Node att="">E</Node>
</Nodes>
就是爱搞怪 2024-10-14 12:50:27

这个小样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:key name="kNodeByAtt" match="Node" use="@att"/>
    <xsl:template match="Node[count(.|key('kNodeByAtt',@att)[1])!=1]"/>
</xsl:stylesheet>

输出:

ACE

编辑:只是为了好玩 XPath 2.0 解决方案

string-join((/Nodes/Node)[index-of(/Nodes/Node/@att,@att)[1]],'')

结果:

ACE

This little stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:key name="kNodeByAtt" match="Node" use="@att"/>
    <xsl:template match="Node[count(.|key('kNodeByAtt',@att)[1])!=1]"/>
</xsl:stylesheet>

Output:

ACE

Edit: Just for fun XPath 2.0 solution

string-join((/Nodes/Node)[index-of(/Nodes/Node/@att,@att)[1]],'')

Result:

ACE
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文