У меня есть файл xml, в котором мне нужно переименовать элементы. (также позже для преобразования элементов в атрибуты). Преобразование xslt вставляет пространство имен по умолчанию во все элементы верхнего уровня. Я не хочу этого. Я видел довольно много вопросов об этой проблеме, но все еще имею проблемы с желаемым результатом и понимаю, почему...
<ar xmlns="">
<dyu xmlns="http://www.coastsystems.net">ábada</dyu>
Почему пространство имен удалено только из ar? И почему он сохраняет xmlns=""?
<xsl:template match="/c:lexique/c:headword">
<ar>
<xsl:apply-templates select="@* | node()"/>
</ar>
</xsl:template>
тогда «исключить префиксы результата», кажется, вообще не имеет никакого эффекта. Будь то там или нет, пространство имен не вставлено. Почему?
Есть ли заминка с xslt3? Мне нужно использовать это, так как оно правильно обрабатывает расширенные латинские символы и сортирует.
XML выглядит следующим образом:
<?xml version='1.0' encoding='utf-8'?>
<lexique xmlns="http://www.coastsystems.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.coastsystems.net headwords2.xsd"
>
<headword>
<dyu>ábada</dyu>
<alt>abada</alt>
<emp></emp>
<cf>fewu</cf>
<trans>
<lang>fr</lang>
<detail></detail>
<speech>
<type></type>
<t-uuid>7b8612bc-23c7-4241-817f-f6fcd9bff8ac</t-uuid>
<def>
<gloss>jamais</gloss>
<gl-id>bbc05aae-8f08-4ab7-91ae-3b52533a896f</gl-id>
<note2></note2>
<note3></note3>
<note4></note4>
<tags></tags>
<example>
<source>a tɛ koɲuman kɛ abada.</source>
<target>Il ne fait jamais quelque chose de bien.</target>
<ex-id>2c592b68-0d29-4b6c-8614-005adab4fba5</ex-id>
</example>
</def>
</speech>
</trans>
</headword>
</lexique>
С таблицей стилей xslt:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:c="http://www.coastsystems.net"
exclude-result-prefixes="xsl c"
>
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="/">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/c:lexique/c:headword">
<ar>
<xsl:apply-templates select="@* | node()"/>
</ar>
</xsl:template>
</xsl:stylesheet>
(xslt3 -xsl:rename.xsl -s:headwords.xml)
Выходы:
<?xml version="1.0" encoding="UTF-8"?>
<lexique xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.coastsystems.net" xsi:schemaLocation="http://www.coastsystems.net headwords2.xsd">
<ar xmlns="">
<dyu xmlns="http://www.coastsystems.net">ábada</dyu>
<alt xmlns="http://www.coastsystems.net">abada</alt>
<emp xmlns="http://www.coastsystems.net"/>
<cf xmlns="http://www.coastsystems.net">fewu</cf>
<trans xmlns="http://www.coastsystems.net">
<lang>fr</lang>
<detail/>
<speech>
<type/>
<t-uuid>7b8612bc-23c7-4241-817f-f6fcd9bff8ac</t-uuid>
<def>
<gloss>jamais</gloss>
<gl-id>bbc05aae-8f08-4ab7-91ae-3b52533a896f</gl-id>
<note2/>
<note3/>
<note4/>
<tags/>
<example>
<source>a tɛ koɲuman kɛ abada.</source>
<target>Il ne fait jamais quelque chose de bien.</target>
<ex-id>2c592b68-0d29-4b6c-8614-005adab4fba5</ex-id>
</example>
</def>
</speech>
</trans>
</ar>
Желаемый результат:
<?xml version="1.0" encoding="UTF-8"?>
<lexique xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.coastsystems.net" xsi:schemaLocation="http://www.coastsystems.net headwords2.xsd">
<ar>
<dyu>ábada</dyu>
<alt>abada</alt>
<emp/>
<cf>fewu</cf>
<trans>
<lang>fr</lang>
<detail/>
===== snipped
Инструкция к exclude-result-prefixes
исключает их только в том случае, если они не используются. Если вы хотите, чтобы эти другие элементы создавались без пространства имен, вам нужно создавать элементы без пространства имен (используя local-name()
) вместо использования xsl:copy
.
Этого можно добиться, добавив общий шаблон для любого элемента (после шаблона удостоверения, который соответствует @*|node()
, чтобы он имел соответствие с более высоким приоритетом.
Если вы хотите, чтобы все элементы были связаны с пространством имен ``, но не с префиксом, установите пространство имен по умолчанию в таблице стилей xmlns="http://www.coastsystems.net"
:
<xsl:stylesheet version="2.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.coastsystems.net"
xmlns:c="http://www.coastsystems.net"
exclude-result-prefixes="xsl c"
>
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="/c:lexique/c:headword">
<ar>
<xsl:apply-templates select="@* | node()"/>
</ar>
</xsl:template>
</xsl:stylesheet>
Вы также можете изменить выражение сопоставления для шаблона удостоверения, чтобы указать конкретные node()
и не включать *
: @*|text()|comment()|processing-instruction()
.
Спасибо Мэдс. Это решило проблему. Но мне не нужно было совпадать с локальным именем. Как только я помещаю xmlns="Coastsystems.net" в заголовок, он больше не вставляет пространство имен.