Невозможно сгруппировать значение элемента с помощью group by в XSLT - PullRequest
0 голосов
/ 14 мая 2019

У меня есть XML лежат ниже:

 <Products>
        <Product1>
            <Reference>000510143244</Reference>
            <Value1>543</Value1>
        </Product1>
    </Products>
    <Products>
        <Product1>
            <Reference>000510143244</Reference>
            <Value1>543</Value1>
        </Product1>
    </Products>
    <Products>
        <Product1>
            <Reference>45768799322</Reference>
            <Value1>543</Value1>
        </Product1>
    </Products>
    <Products>
        <Product2>
            <Reference>35726318090</Reference>
            <Value1>543</Value1>
        </Product2>
    </Products>
    <Products>
        <Product2>
            <Reference>35726318090</Reference>
            <Value1>543</Value1>
        </Product2>
    </Products>

Я хочу получить только первое значение ссылки на Product1 ... но я не могу этого получить. Также не обязательно, чтобы Product 1 всегда был первым элементом входного xml.

Любые предложения, как я могу получить это?

Я попытался получить значение как:

<xsl:template match="//Products">
  <xsl:variable name="Product1">
    <xsl:for-each-group select="/Reference" group-by="/Reference">
        <xsl:copy-of select="." />
    </xsl:for-each-group>
  </xsl:variable>
</xsl:template>

Обновление: 1

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="Products[child::Product1][1]">

        <xsl:value-of select="." />

    </xsl:template>

    <xsl:template match="text()" />
</xsl:stylesheet>

Мой ожидаемый результат: 000510143244

1 Ответ

2 голосов
/ 14 мая 2019

Чтобы получить первое вхождение <Products> с <Product1>, вам может потребоваться сопоставить родительский тег или корневой тег вашего входного XML.

Предполагая ваш ввод, как показано ниже:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<root>
    <Products>
        <Product2>
            <Reference>35726318090</Reference>
        </Product2>
    </Products>
    <Products>
        <Product1>
            <Reference>02563899183</Reference>
        </Product1>
    </Products>
    <Products>
        <Product1>
            <Reference>000510143244</Reference>
        </Product1>
    </Products>
    <Products>
        <Product1>
            <Reference>000510143244</Reference>
        </Product1>
    </Products>
    <Products>
        <Product2>
            <Reference>35726318090</Reference>
        </Product2>
    </Products>
</root>

Следующий код может дать вам результат:

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="root">
        <xsl:for-each-group select="Products/Product1" group-by="Reference">
            <xsl:copy-of select="current-group()[1]" />
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

См. Демонстрацию: https://xsltfiddle.liberty -development.net / 3NJ38Zx

Обновление:

ИЛИ вы можете просто достичь этого с помощью следующего кода:

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="Products[child::Product1][1]">
        <xsl:copy-of select="." />
    </xsl:template>

    <xsl:template match="text()" />
</xsl:stylesheet>

Обновление 2:

    <xsl:template match="root">
        <xsl:variable name="ref">
            <xsl:for-each-group select="Products/Product1" group-by="Reference">
                <xsl:copy-of select="current-group()[1]/Reference" />
            </xsl:for-each-group>
        </xsl:variable>
        <xsl:value-of select="$ref"/>
    </xsl:template>

https://xsltfiddle.liberty -development.net / 3NJ38Zx / 1

Обновление 3:

Вы не можете присвоить значение глобальной переменной из шаблона.

Есть два способа получить то, что вам нужно.

1) Создайте глобальную переменную, как показано ниже, которая будет занимать сначала <Products>, чей дочерний элемент равен <Product1>, и будет отображать ее Reference

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:variable name="ref" select="root/Products[child::Product1][1]/Product1/Reference" />

    <xsl:template match="/">
        <xsl:value-of select="$ref" />
    </xsl:template>

</xsl:stylesheet>

2) Вы можете изменить шаблон, как показано ниже, чтобы получить результат.

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="Products[child::Product1][1]/Product1/Reference">
        <xsl:value-of select="." />
    </xsl:template>

    <xsl:template match="text()" />
</xsl:stylesheet>
...