如何获得不同的节点集?

时间:2016-01-12 10:07:21

标签: xml nodes xslt-2.0

如何从文档中检索不同的节点集? 我玩过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节点中,不同的值,我仍然只想要输出中有一个节点集??

谢谢!

2 个答案:

答案 0 :(得分:1)

假设您正在使用NodeJS进行服务器端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);
  });
});

答案 1 :(得分:1)

您可以使用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))]"/>