XslCompiledTransform не работает, если файл xml содержит xmlns - PullRequest
1 голос
/ 16 сентября 2011

У меня есть простой XML-файл с простым XSLT-преобразованием, и XslCompiledTransform хорошо работает, когда в моем XML-файле нет xmlns, но когда я получаю, XML-файл пуст - почему?

Вот мой код:

    public static void XmlToXmlWithXsl(string xmlFilePath, string xmlOutputFilePath, string xslFilePath)
    {
        // Load the style sheet.
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(xslFilePath);

        // Create the writer.
        XmlWriterSettings settings = xslt.OutputSettings;
        XmlWriter writer = XmlWriter.Create(xmlOutputFilePath, settings);

        // Execute the transformation.
        xslt.Transform(xmlFilePath, writer);
        writer.Close();
    }

Вот мой XML (версия с xmlns):

<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blah">
    <message>
        <id>blah</id>
        <text>Polski</text>
        <text lang="en">English</text>
        <notes />
    </message>

    <message>
        <id>blah2</id>
        <text lang="pl">Polski</text>
        <text lang="en">English</text>
        <notes />
    </message>
</messages>

Вот мой XSL (немного меньше, чем был):

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

    <xsl:variable name="empty_string"></xsl:variable>

    <!-- root -->
    <xsl:template match="/">
        <xsl:element name="messages">
            <xsl:apply-templates select="//message" />
        </xsl:element>
    </xsl:template>

    <!-- AS-IS with xml content -->
    <xsl:template match="message">
        <xsl:element name="{name(.)}"><xsl:apply-templates /></xsl:element>
    </xsl:template>

    <!-- AS-IS with text content -->
    <xsl:template match="id|notes|text">
        <xsl:element name="{name(.)}"><xsl:value-of select="." /></xsl:element>
    </xsl:template>

</xsl:stylesheet>

Вывод:

<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blablabla" />

Выходные данные должны быть:

<?xml version="1.0" encoding="utf-8"?>
<messages xmlns="blablabla">
  <message>
        <id>blah</id>
        <text>Polski</text>
        <text>English</text>
        <notes></notes>
    </message>
  <message>
        <id>blah2</id>
        <text>Polski</text>
        <text>English</text>
        <notes></notes>
    </message>
</messages>

1 Ответ

3 голосов
/ 16 сентября 2011

Это часто задаваемые вопросы XSLT / XPath 1.0: чтобы выбрать или сопоставить элементы в определенном пространстве имен, даже в пространстве имен по умолчанию, в XSLT / XPath 1.0 вам необходимо привязать префикс к URI пространства имен и использовать этот префикс в выражениях пути илисопоставлять шаблоны для определения имен элементов:

<xsl:stylesheet version="1.0"
    xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
    xmlns:df="blablabla"
>
    <xsl:output method="xml" indent="yes" />
<xsl:variable name="empty_string"></xsl:variable>

<!-- root -->
<xsl:template match="/">
    <xsl:element name="messages">
        <xsl:apply-templates select="//df:message" />
    </xsl:element>
</xsl:template>

<!-- AS-IS with xml content -->
<xsl:template match="df:message">
    <xsl:element name="{name(.)}"><xsl:apply-templates /></xsl:element>
</xsl:template>

<!-- AS-IS with text content -->
<xsl:template match="df:id|df:notes|df:text">
    <xsl:element name="{name(.)}"><xsl:value-of select="." /></xsl:element>
</xsl:template>

...