如何获得不同的节点集?

How to get distinct node sets?

如何从文档中检索不同的节点集? 我玩过 distinct-values 函数,但它没有给我想要的结果。看这个例子:

这个样式表,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">

<xsl:template match="/">
    <xsl:variable name="distinct">
        <foo>
            <a>1</a>
            <b>2</b>
        </foo>
        <foo>
            <a>1</a>
            <b>2</b>
        </foo>
        <foo>
            <a>3</a>
            <b>4</b>
        </foo>
    </xsl:variable>

    <result>
        <xsl:copy-of select="distinct-values($distinct/foo)"/>
    </result>
</xsl:template>

应用于任何文件都会给我

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:xs="http://www.w3.org/2001/XMLSchema">12 34</result>

显然它认识到节点集 foo[1]foo[2] 是相同的,但它只输出每个节点的值,而不是节点集本身。

我想要这样的输出:

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:aux="http://dummy">
    <foo>
        <a>1</a>
        <b>2</b>
    </foo>
    <foo>
        <a>3</a>
        <b>4</b>
     </foo>
</result>

重复节点可以按任何顺序分布在整个文档中。

问题的小更新:如果我只需要检查子节点 a 而不是 b 的唯一性,我该怎么办(就像在我的示例中,在前两个 foo 节点中,值完全不同,我仍然在输出中只需要一个节点集)?

谢谢!

假设你在这里用 NodeJS 做 server-side JS(基于有问题的标签)?

尝试检查 NPM 模块以找到合适的 XML 包,它可以为您解析 XML,或者翻译成 JavaScript。

xml2js 是一个看起来可能有用的模块。我会做一些研究并更新这个答案,但是把它放在这里作为占位符,让你有机会检查 NPM 是否有可能有帮助的模块。

这是一些工作代码:

foo.xml(修改为概念证明):

<start>
  <foo>
    <a>1</a>
    <b>2</b>
  </foo>
  <foo>
    <a>1</a>
    <b>2</b>
  </foo>
  <foo>
    <a>3</a>
    <b>4</b>
  </foo>
</start>

app.js:

var fs = require('fs'),
  xml2js = require('xml2js'),
  _ = require('lodash');

var parser = new xml2js.Parser();

fs.readFile(__dirname + '/foo.xml', function(err, data) {
  parser.parseString(data, function (err, result) {
    var res = _.uniq(result.start.foo, function (n) {
      return JSON.toString(n);
    });
    console.log(res);
  });
});

有一个函数 deep-equal 您可以使用:<xsl:copy-of select="$distinct/foo[every $foo in following::foo satisfies not(deep-equal(., $foo))]"/>。或者反过来:<xsl:copy-of select="$distinct/foo[every $foo in preceding::foo satisfies not(deep-equal(., $foo))]"/>.