XSLT выберите уникальный узел - PullRequest
4 голосов
/ 21 ноября 2011

это сводит меня с ума, для xslt новичка, как я.

Ввод:

<root>
    <a><name>kyle</name></a>
    <b><name>stan</name></b>
    <b><name>wendy</name></b>
    <b><name>cece</name></b>
</root>

Ожидаемый результат:

<root>
        <a><name>kyle</name></a>
        <b><name>stan</name></b>
</root>

Меня попросили вернуться первымуникальный узел под 'root', как мне это сделать?

Либо xslt 1.0, либо 2.0 подойдет.

Большое вам спасибо !!!!

Ответы [ 2 ]

1 голос
/ 21 ноября 2011

Решение XSLT 2.0:

<?xml version="2.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
  <root>
    <xsl:for-each-group select="root/*" group-by="local-name()">
      <xsl:copy-of select="."/>
    </xsl:for-each-group>
    </root>
  </xsl:template>
</xsl:stylesheet>

Выход:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <a>
      <name>kyle</name>
  </a>
   <b>
      <name>stan</name>
  </b>
</root>
1 голос
/ 21 ноября 2011

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

Пример XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="/*/*[preceding-sibling::*[name() = current()/name()]]"/> 

</xsl:stylesheet>

Выход (с использованием Saxon 9 HE):

<root>
   <a>
      <name>kyle</name>
   </a>
   <b>
      <name>stan</name>
   </b>
</root>
...