#xml #xslt
#xml #xslt
Вопрос:
Вот мой (упрощенный для данного случая) XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test_1.xsl" type="text/xsl"?>
<doc xmlns="http://www.foo.org">
<div>
<title>Mr. Title</title>
<paragraph>This is one paragraph.
</paragraph>
<paragraph>Another paragraph.
</paragraph>
</div>
</doc>
И вот мой XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foo="http://www.foo.org">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo:doc">
<xsl:element name="newdoc" namespace="http://www/w3.org/1999/xhtml">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="foo:div">
<segment title="{foo:title}">
<xsl:apply-templates/>
</segment>
</xsl:template>
<xsl:template match="foo:title">
<xsl:element name="h2">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="foo:paragraph">
<xsl:element name="p">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
На выходе получается следующее:
<newdoc xmlns="http://www/w3.org/1999/xhtml">
<segment xmlns="" title="Mr. Title">
<h2>Mr. Title</h2>
<p>This is one paragraph.
</p>
<p>Another paragraph.
</p>
</segment>
</newdoc>
что замечательно, за исключением xmlns =»» в элементе segment, который, похоже, не определяет пространство имен для себя и всех своих дочерних элементов. Как я могу заставить его не добавлять это?
Примечание: Я также попытался преобразовать первый узел с
<xsl:template match="mydoc:doc">
<html xmlns="http://www/w3.org/1999/xhtml">
<xsl:apply-templates/>
</html>
</xsl:template>
вместо этого, но это приводит к тому же эффекту.
Спасибо полезным людям!
Ответ №1:
Похоже, вы хотите поместить все элементы выходного документа в «http://www/w3.org/1999/xhtml «пространство имен. В настоящее время вы указываете пространство имен только для элемента «newdoc», все остальные элементы находятся в пространстве имен по умолчанию, поскольку в вашей таблице стилей нет объявления пространства имен. Вложение внутри таблицы стилей определяет, к какому пространству имен принадлежат элементы, а не вложение после преобразования.
Вы можете объявить пространство имен по умолчанию в своей таблице стилей, чтобы повлиять на все элементы, не отвечающие требованиям:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foo="http://www.foo.org"
xmlns="http://www.w3.org/1999/xhtml">
Теперь вам также больше не нужен xsl:element
тег и вы можете напрямую использовать newdoc
для создания элемента в правильном пространстве имен.
Комментарии:
1. У меня это тоже сработало, но в ответе есть опечатка. В ответе говорится, что
http://www/w3.org ...
в нем должно быть указаноhttp://www.w3.org ...
. Косая черта должна быть точкой.
Ответ №2:
В foo:div
шаблоне вы создаете segment
элемент с пустым пространством имен. Поскольку родительский элемент имеет другое пространство имен, процессор должен добавить это объявление пространства имен.
Если вам нужно segment
то же пространство имен, что и родительское, тогда используйте xsl:element
вместо:
<xsl:template match="foo:div">
<xsl:element name="segment">
<xsl:attribute name="title">
<xsl:value-of select="foo:title"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>