build xml динамически на основе ввода с xslt1.0 - PullRequest
0 голосов
/ 26 мая 2020

привет, вы хотите создать xslt, который создает этот xml динамически.

Результат должен быть:

<Products>
    <Product productCode="SQUARE-BLUE-EXTRA-A-10-MAY" messageTag="SquareMessage"/>
    <Product productCode="SQUARE-RED-EXTRA-B-20-JUNE" messageTag="SquareMessage"/>
    <Product productCode="TRIANGLE-BLUE" messageTag="TriangleMessage"/>
</Products>

это мой вход xml

<Root>
    <Object>
        <QuoteLineItems>
            <Object>
                <Product2Id>
                    <ProductCode>SQUARE</ProductCode>
                </Product2Id>
                <QuoteLineItems>
                    <Object>
                        <Product2Id>
                            <ProductCode>BLUE</ProductCode>
                        </Product2Id>
                        <QuoteLineItems>
                            <Object>
                                <ServiceDate>MAY</ServiceDate>
                                <attributes>
                                    <Object>
                                        <attributeuniquecode>ATTR_VOLUMEPERCENTAGE</attributeuniquecode>
                                        <attributedisplayname>Volume percentage</attributedisplayname>
                                        <value>10</value>
                                    </Object>
                                    <Object>
                                        <attributeuniquecode>ATTR_TYPE</attributeuniquecode>
                                        <attributedisplayname>Type</attributedisplayname>
                                        <value>A</value>
                                    </Object>
                                </attributes>
                                <Product2Id>
                                    <ProductCode>EXTRA</ProductCode>
                                </Product2Id>
                                <QuoteLineItems/>
                            </Object>
                        </QuoteLineItems>
                    </Object>
                    <Object>
                        <Product2Id>
                            <ProductCode>RED</ProductCode>
                        </Product2Id>
                        <QuoteLineItems>
                            <Object>
                                <ServiceDate>JUNE</ServiceDate>
                                <attributes>
                                    <Object>
                                        <attributeuniquecode>ATTR_VOLUMEPERCENTAGE</attributeuniquecode>
                                        <attributedisplayname>Volume percentage</attributedisplayname>
                                        <value>20</value>
                                    </Object>
                                    <Object>
                                        <attributeuniquecode>ATTR_TYPE</attributeuniquecode>
                                        <attributedisplayname>Type</attributedisplayname>
                                        <value>B</value>
                                    </Object>
                                </attributes>
                                <Product2Id>
                                    <ProductCode>EXTRA</ProductCode>
                                </Product2Id>
                                <QuoteLineItems/>
                            </Object>
                        </QuoteLineItems>
                    </Object>
                </QuoteLineItems>
            </Object>
            <Object>
                <Product2Id>
                    <ProductCode>TRIANGLE</ProductCode>
                </Product2Id>
                <QuoteLineItems>
                    <Object>
                        <Product2Id>
                            <ProductCode>BLUE</ProductCode>
                        </Product2Id>
                    </Object>
                </QuoteLineItems>
            </Object>
        </QuoteLineItems>
    </Object>
</Root>

input xml может быть расширен, поэтому он должен быть динамическим c. Позже я также хочу удалить продукты с повторяющимися атрибутами productCode.

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

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

я адаптировал ваш xslt.

еще несколько вещей, которые я не могу понять

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:output indent="yes"/>
    <xsl:template match="node()">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="Root">
        <Products>
            <xsl:apply-templates/>
        </Products>
    </xsl:template>
    <xsl:template match="QuoteLineItems/Object[not(QuoteLineItems/Object)]">
        <xsl:choose>
            <xsl:when test="Product2Id/ProductCode='EXTRA'">
                <Product messageTag="{../../../../Product2Id/ProductCode}Message">
                    <xsl:attribute name="productCode"><xsl:apply-templates select="ancestor-or-self::Object/Product2Id/ProductCode | ServiceDate | attributes/Object[attributeuniquecode='ATTR_VOLUMEPERCENTAGE']/value | attributes/Object[attributeuniquecode='ATTR_TYPE']/value" mode="product-code-value"/></xsl:attribute>
                </Product>
            </xsl:when>
            <xsl:otherwise>
                <Product messageTag="{../../Product2Id/ProductCode}Message">
                    <xsl:attribute name="productCode"><xsl:apply-templates select="ancestor-or-self::Object/Product2Id/ProductCode | ServiceDate | cpq_ServiceEndDate | attributes/Object[attributeuniquecode='ATTR_VOLUMEPERCENTAGE']/value | attributes/Object[attributeuniquecode='ATTR_TYPE']/value" mode="product-code-value"/></xsl:attribute>
                </Product>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*" mode="product-code-value">
        <xsl:if test="position() > 1">-</xsl:if>
        <xsl:value-of select="."/>
    </xsl:template>
</xsl:stylesheet>

вывод:

<?xml version="1.0" encoding="UTF-8"?>
<Products>
    <Product messageTag="SQUAREMessage" productCode="SQUARE-BLUE-MAY-10-A-EXTRA"/>
    <Product messageTag="SQUAREMessage" productCode="SQUARE-RED-JUNE-20-B-EXTRA"/>
    <Product messageTag="TRIANGLEMessage" productCode="TRIANGLE-BLUE"/>
</Products>

значение 'EXTRA 'находится в конце, и я хочу, чтобы оно было третьим значением в productCode. так что это должно быть: SQUARE-BLUE-EXTRA-MAY-10-A

другая проблема, с которой я борюсь, это. в моем исходном сообщении дата - это не просто месяц, а реальная дата в следующем формате: «2020-06-01». Есть ли способ удалить тире - только из данных. чтобы он не мешал тире в атрибуте productCode?

0 голосов
/ 26 мая 2020

Я думаю, что в XSLT 2 или 3 вы могли бы string-join значения, но в XSLT 1, чтобы заполнить этот атрибут, вам нужно sh их через шаблон (или вы также можете использовать для каждого) :

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

<xsl:output indent="yes"/>

<xsl:template match="node()">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="Root">
    <Products>
        <xsl:apply-templates/>
    </Products>
</xsl:template>

<xsl:template match="QuoteLineItems/Object[not(QuoteLineItems/Object)]">
    <Product messageTag="{Product2Id/ProductCode}Message">
        <xsl:attribute name="productCode">
            <xsl:apply-templates select="ancestor-or-self::Object/Product2Id/ProductCode | ServiceDate | attributes/Object/value" mode="product-code-value"/>
        </xsl:attribute>
    </Product>
</xsl:template>

<xsl:template match="*" mode="product-code-value">
    <xsl:if test="position() > 1">-</xsl:if>
    <xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6pS26n7/1

Конечно, если вы хотите удалить дубликаты позже, кажется сомнительным объединение значений в значение атрибута, если разные элементы необходимы для ключа, поскольку разбить значения атрибутов сложнее, чем работать с набором узлов, но, возможно, это другая проблема.

...