Избавьтесь от корневого узла XML в выводе шаблона XSL - PullRequest
2 голосов
/ 23 июня 2009

Я использую шаблоны XSL в качестве шаблонов веб-страниц для веб-фреймворка, конечный результат - XHTML 1.0 Strict; он принимает ввод XML и выводит XHTML. Он работает отлично, за исключением одной проблемы - конечный вывод также выводит узел XML, а не только содержимое. Вот базовый XML (некоторые элементы отсутствуют, но общий дизайн такой же):

<Page>
    <PageScript>
        <Script>./js/myscript.js</Script>
    </PageScript>
    <PageCSS>
        <CSS>./css/mycss.css</CSS>
    </PageCSS>
    <PageContent>Blah blah blah</PageContent>
</Page>

Вот шаблон XSL

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:response="http://www.ntforl.com/"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:lang="en">

    <xsl:output
        method="xml"
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
        doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    />

    <xsl:template match="//PageCSS">
        <xsl:for-each select="CSS">
            <link type="text/css" rel="stylesheet">
                <xsl:attribute name="href">
                    <xsl:value-of select="." />
                </xsl:attribute>
            </link>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="//PageScript">
        <xsl:for-each select="Script">
            <script type="text/javascript">
                <xsl:attribute name="src">
                    <xsl:value-of select="." />
                </xsl:attribute>
            </script>
        </xsl:for-each>
    </xsl:template>

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

    <xsl:template match="/" disable-output-escaping="yes">
        <html>
            <head>
                <title>
                    <xsl:value-of select="//PageTitle" />
                </title>
                <meta http-equiv="content-type" content="text/html;charset=utf-8" />
                <link type="text/css" rel="stylesheet" href="template/style/globalStyle.css" />
                <link type="text/css" rel="stylesheet" href="template/style/standards.css" />
                <xsl:apply-templates select="//PageCSS" />
                <script type="text/javascript" src="template/js/some_file.js"></script>
                <xsl:apply-templates select="//PageScript" />
            </head>
            <body onload="">
                <div id="container">
                    <div id="top">
                        <div class="clear" />
                    </div>
                    <div id="main">
                        <div class="left" style="width: 708px; margin-top: 10px;">
                            <h1 class="center">
                                <xsl:value-of select="//PageTitle" />
                            </h1>
                        </div>
                        <div class="clear" />
                        <div id="rightPane">
                            <div id="rightPaneContent">
                                <xsl:apply-templates select="//PageContent" />
                            </div>
                            <img src="template/images/mainBgBottom.png" alt="" />
                        </div>
                    </div>
                </div>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

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

<PageContent xmlns=""> node content </PageContent>

в XHTML. Мне нужно знать, как от него избавиться, чтобы у меня был действительный документ XHTML 1.0 Strict.

Странно то, что узел PageContent является единственным узлом, который делает это, никакой другой узел не получает его содержимое, обернутое с именем узла в выходных данных. В чем причина такого поведения?

Ответы [ 3 ]

3 голосов
/ 23 июня 2009

Вы звоните apply-templates на узле PageContent:

<xsl:apply-templates select="//PageContent" />

Этот шаблон соответствует только этому шаблону, поэтому узел PageContent копируется:

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

Возможно, вам следует добавить еще один шаблон, который соответствует PageContent и просто обрабатывает дочерние узлы, не копируя сам PageContent:

<xsl:template match="//PageContent">
  <xsl:apply-templates/>
</xsl:template>
2 голосов
/ 23 июня 2009

Как уже отмечали @sth и @molf, вы получаете узел, скопированный вашим шаблоном идентификации (<xsl:template match="@*|node()">), потому что ни один другой шаблон в вашей таблице стилей не соответствует <PageContent> узлам.

В качестве альтернативы решениям, уже представленным двумя другими, вы можете изменить шаблон удостоверения на:

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

Когда <PageContent> встречается сейчас, шаблон идентификации больше не совпадает. Вместо этого будет использоваться неявный шаблон по умолчанию для элементов:

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

Это означает, что шаблоны будут автоматически применяться к дочерним элементам <PageContent>, а сам узел копироваться не будет - именно то, что вы хотите.

2 голосов
/ 23 июня 2009

Я бы попробовал заменить <xsl:apply-templates select="//PageContent" /> на:

<xsl:apply-templates select="//PageContent/node()" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...