XSL находит узлы, которые имеют ключ как одноуровневый

У меня есть этот (довольно странный) XML с 7 детьми из 4 семей. Есть 5 мальчиков с 6 яблоками и 9 апельсинами и 2 девочки с 3 яблоками и 3 апельсинами.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="fruits.xsl"?>
<report>
    <family>
        <gender>
            <boyorgirl>Boy</boyorgirl>
                <person>
                    <apples>1</apples>
                    <oranges>1</oranges>
                    <id>1</id>
                </person>
        </gender>
        <gender>
            <boyorgirl>Girl</boyorgirl>
                <person>
                    <apples>2</apples>
                    <oranges>0</oranges>
                    <id>2</id>
                </person>
        </gender>
        <gender>
            <boyorgirl>Boy</boyorgirl>
                <person>
                    <apples>1</apples>
                    <oranges>4</oranges>
                    <id>3</id>
                </person>
        </gender>
    </family>
    <family>
        <gender>
            <boyorgirl>Girl</boyorgirl>
                <person>
                    <apples>1</apples>
                    <oranges>3</oranges>
                    <id>4</id>
                </person>
        </gender>
    </family>
    <family>
        <gender>
            <boyorgirl>Boy</boyorgirl>
                <person>
                    <apples>1</apples>
                    <oranges>0</oranges>
                    <id>5</id>
                </person>
        </gender>
    </family>
    <family>
        <gender>
            <boyorgirl>Boy</boyorgirl>
                <person>
                    <apples>2</apples>
                    <oranges>2</oranges>
                    <id>6</id>
                </person>
                <person>
                    <apples>1</apples>
                    <oranges>2</oranges>
                    <id>7</id>
                </person>
        </gender>
    </family>
</report>

Я хочу посчитать, сколько человек для каждого пола, и сколько яблок и апельсинов у них вместе. Я не хочу жестко указывать пол в те современные дни, на случай, если кто-то скажет, что у него другой пол, нежели мальчик или девочка. Ожидаемый результат

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<fruitcounting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <fruitline>
        <boyorgirl>Boy</boyorgirl>
        <numberOfPersons>5</numberOfPersons>
        <apples>6</apples>
        <oranges>9</oranges>
    </fruitline>
    <fruitline>
        <boyorgirl>Girl</boyorgirl>
        <numberOfPersons>2</numberOfPersons>
        <apples>3</apples>
        <oranges>3</oranges>
    </fruitline>
</fruitcounting>

У меня есть начало таблицы стилей, но она просто считает членов и фрукты в первой семье - как я могу изменить ее, чтобы она нашла всех мальчиков / девочек, независимо от семьи? Или, я думаю, я мог бы сформулировать это как все узлы, которые имеют ключ как предшествующий брат.

Я могу использовать только XSL 1.0 без расширений

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:key name="fruits" match="gender" use="boyorgirl"/>

<xsl:template match="/">
    <fruitcounting>

        <xsl:for-each select="//gender[generate-id(.)=generate-id(key('fruits', boyorgirl)[1])]">

            <fruitline>
                <boyorgirl><xsl:value-of select="boyorgirl"/></boyorgirl>
                <numberOfPersons><xsl:value-of select="count(../gender/person/id)"/></numberOfPersons>
                <apples><xsl:value-of select="sum(../gender/person/apples)"/></apples>
                <oranges><xsl:value-of select="sum(../gender/person/oranges)"/></oranges>

            </fruitline>

        </xsl:for-each>
    </fruitcounting>
</xsl:template>

</xsl:stylesheet>

1 ответ

Решение

Вы можете заменить <numberOfPersons><xsl:value-of select="count(../gender/person/id)"/></numberOfPersons> с <numberOfPersons><xsl:value-of select="count(key('fruits', boyorgirl)/person)"/></numberOfPersons> и использовать key действовать так же, чтобы идентифицировать ваши группы, например, <apples><xsl:value-of select="sum(key('fruits', boyorgirl)/person/apples)"/></apples> в других вычислениях.

Таким образом, полный код становится

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:key name="fruits" match="gender" use="boyorgirl"/>

<xsl:template match="/">
    <fruitcounting>

        <xsl:for-each select="//gender[generate-id(.)=generate-id(key('fruits', boyorgirl)[1])]">

            <fruitline>
                <boyorgirl><xsl:value-of select="boyorgirl"/></boyorgirl>
                <numberOfPersons><xsl:value-of select="count(key('fruits', boyorgirl)/person)"/></numberOfPersons>
                <apples><xsl:value-of select="sum(key('fruits', boyorgirl)/person/apples)"/></apples>
                <oranges><xsl:value-of select="sum(key('fruits', boyorgirl)/person/oranges)"/></oranges>

            </fruitline>

        </xsl:for-each>
    </fruitcounting>
</xsl:template>

</xsl:stylesheet>

онлайн на http://xsltransform.net/bwdwsb.

Другие вопросы по тегам