xslt выравнивает любой XML-файл

#xml #xslt #transform

#xml #xslt #преобразование

Вопрос:

В качестве примера приведен следующий XML:

 <?xml version="1.0" encoding="UTF-8"?>
<Message>
<MessageID>1</MessageID>
<MessageType>0</MessageType>
<UniqueRef>12</UniqueRef>
<CreatedBy>fooo.bar</CreatedBy>
<Product>
    <Name>Food Mixer</Name>
    <Origin>London</Origin>
    <CreatedBy>foo.bar</CreatedBy>
</Product>
<ProductExtendedProperties>
    <CreateDate>23/10/2010</CreateDate>
    <CreatedBy>foo.bar</CreatedBy>
</ProductExtendedProperties>
<Items>
    <Item>
        <Title>Food Mixer</Title>
        <CreatedBy>my.customer</CreatedBy>
    </Item>
</Items>
  

Возможно ли создать xslt, который является универсальным в том смысле, что он будет принимать любой брошенный в него элемент, вложенный или нет, и предоставлять красиво отформатированный html.

Что-то вроде этого:

 <html>
<body>
    <fieldset>
        <legend>Message</legend>
        <div>
            <p>MessageID: 1</p>
            <p>MessageType: 0</p>
            <p>UniqueRef: 0</p>
            <p>CreatedBy: foo.bar</p>

            <div>
                <p>Product:</p>
                <ul>
                    <li>Name: Food Mixer</li>
                    <li>Origin: London</li>
                    <li>CreatedBy: foo.bar</li>
                </ul>
            </div>
            <div>
                <p>ProductExtendedProperties:</p>
                <ul>
                    <li>CreateDate: 23/10/2010</li>
                    <li>CreatedBy: foo.bar</li>
                </ul>
            </div>
            <div>
                <p>
                    Items
                </p>
                <div>
                    <p>Item 1:</p>
                    <ul>
                        <li>Title: Food Mixer</li>
                        <li>CreatedBy: my.customer</li>
                    </ul>
                </div>


            </div>
        </div>
    </fieldset>
</body>
  

это не обязательно должно быть таким сложным, просто что-то, что форматирует во вложенные элементы списка все имена и значения элементов на самом деле.

Я понятия не имею, с чего начать с xslt

Любая помощь высоко ценится, спасибо

Ответ №1:

Я думаю, что люди будут гораздо более способны помочь вам, если вы начнете, а затем конкретно объясните, где вам нужна помощь, чтобы из вашего предпринятого решения получить то, что вам нужно.

Например. вы могли бы начать с шаблона, который применяет шаблоны к "*" (любому дочернему элементу), и другого шаблона, который соответствует "*" и использует local-name() для вывода имени текущего элемента (вместе с желаемой разметкой).

Комментарии:

1. Звучит как комментарий, а не как ответ.

2. @ceving: Это началось как комментарий. Но OP сказал: «Я понятия не имею, с чего начать с xslt… Любая помощь высоко ценится». Я предложил, с чего начать (а также способ добиться прогресса в решении вопроса). В то время у OP не было ответов. Я решил, что это подходит как ответ.

Ответ №2:

Один из способов:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml"/>
    <xsl:template match="/*" priority="1">
        <html>
            <body>
                <fieldset>
                    <legend>
                        <xsl:value-of select="name()"/>
                    </legend>
                    <div>
                        <xsl:apply-templates/>
                    </div>
                </fieldset>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="/*/*[not(*)]" priority="1">
        <p>
            <xsl:apply-templates/>
        </p>
    </xsl:template>
    <xsl:template match="*[*]">
        <div>
            <p>
                <xsl:value-of select="concat(name(),':')"/>
            </p>
            <xsl:apply-templates/>
        </div>
    </xsl:template>
    <xsl:template match="*[not(*)][position()!=1]"/>
    <xsl:template match="*[not(*)][1]">
        <ul>
            <xsl:apply-templates select="../*" mode="makeLi"/>
        </ul>
    </xsl:template>
    <xsl:template match="*" mode="makeLi">
        <li>
            <xsl:apply-templates/>
        </li>
    </xsl:template>
    <xsl:template match="text()">
        <xsl:value-of select="concat(name(..),': ',.)"/>
    </xsl:template>
</xsl:stylesheet>
  

Вывод:

 <html>
    <body>
        <fieldset>
            <legend>Message</legend>
            <div>
                <p>MessageID: 1</p>
                <p>MessageType: 0</p>
                <p>UniqueRef: 12</p>
                <p>CreatedBy: fooo.bar</p>
                <div>
                    <p>Product:</p>
                    <ul>
                        <li>Name: Food Mixer</li>
                        <li>Origin: London</li>
                        <li>CreatedBy: foo.bar</li>
                    </ul>
                </div>
                <div>
                    <p>ProductExtendedProperties:</p>
                    <ul>
                        <li>CreateDate: 23/10/2010</li>
                        <li>CreatedBy: foo.bar</li>
                    </ul>
                </div>
                <div>
                    <p>Items:</p>
                    <div>
                        <p>Item:</p>
                        <ul>
                            <li>Title: Food Mixer</li>
                            <li>CreatedBy: my.customer</li>
                        </ul>
                    </div>
                </div>
            </div>
        </fieldset>
    </body>
</html>