Сортировка элементов по значению и удаление дубликатов - PullRequest
2 голосов
/ 20 апреля 2011

У меня есть следующий ввод:

<?xml version="1.0" encoding="utf-8"?>
<NewTerms>
  <newTerm>XPath</newTerm>
  <newTerm>AutoValue</newTerm>
  <newTerm>XPath</newTerm>
  <newTerm>context</newTerm>
  <newTerm>AutoValue</newTerm>
  <newTerm>language files</newTerm>
   <newTerm>AutoValue</newTerm>
  <newTerm>.NET</newTerm>
  <newTerm>XPath</newTerm>
</NewTerms>

Я хочу отсортировать его, и он прекрасно работает со следующим:

  <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

  <xsl:template match="@*|node()">  
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:sort select="."/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Проблема в том, что я получаю (очевидно) отсортированный список вывода с повторяющимися элементами с одинаковыми значениями (например, XPath, AutoValue). Я хочу иметь отсортированный список без повторяющихся значений. То есть я хочу, чтобы каждое значение в отсортированном XML-выводе было только один раз.

Пожалуйста, есть предложения?

Ответы [ 2 ]

2 голосов
/ 21 апреля 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kNewTermByValue" match="newTerm" use="."/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="NewTerms">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates
             select="newTerm[count(.|key('kNewTermByValue',.)[1])=1]">
                <xsl:sort/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<NewTerms xp_0:noNamespaceSchemaLocation="../XSD\CC-CustomDocuTags.xsd" xmlns:xp_0="http://www.w3.org/2001/XMLSchema-instance">
    <newTerm>.NET</newTerm>
    <newTerm>AutoValue</newTerm>
    <newTerm>context</newTerm>
    <newTerm>EPF</newTerm>
    <newTerm>language files</newTerm>
    <newTerm>XPath</newTerm>
</NewTerms>

Примечание : не сортировать атрибуты и дочерние элементы вместе, поскольку вы не можете вывести атрибут послевы выводите детей.

1 голос
/ 20 апреля 2011

Вы должны отфильтровать выбор вашего вида:

<xsl:template match="@*|node()[not(preceding::node()=.)]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()">
            <xsl:sort select="."/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

И это даст вам желаемый результат:

<?xml version="1.0"?>
<NewTerms>
    <newTerm>.NET</newTerm>
    <newTerm>AutoValue</newTerm>AutoValueAutoValue
    <newTerm>EPF</newTerm>
    <newTerm>XPath</newTerm>XPathXPath
    <newTerm>context</newTerm>
    <newTerm>language files</newTerm>
</NewTerms>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...