【发布时间】:2023-04-05 03:28:01
【问题描述】:
我有一个 XSL,我需要按照以下方式生成输出:
<moo xmlns="http://api.example.com">
<foo>1358944586848</foo>
<bar>
<a>1</a>
<b>2</b>
<c>3</c>
</bar>
</moo>
我可以这样做:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://api.example.com">
<xsl:template match="/">
<xsl:element name="moo">
<!-- and so on -->
但是,我有点讨厌在我的 xsl 文件中使用 xsl 前缀,因为我觉得它很混乱。无论如何,使用 XPath 选择很容易,因为如果需要,您可以将 xpath-default-namespace 设置为您要转换的任何内容。但是据我所知,没有可用的element-default-namespace,那么我怎样才能以一种好的方式生成想要的输出呢?
我知道我可以做到:
<stylesheet version="2.0"
xmlns="http://www.w3.org/1999/XSL/Transform">
<template match="/">
<element name="moo" namespace="http://api.example.com">
<!-- and so on -->
但是我必须在我创建的每个元素上显式设置此命名空间,否则它们最终将使用 XSL 命名空间。那么有没有一种干净的方法来创建具有特定命名空间(不带前缀)的元素并且不触及 xsl 文件的默认命名空间?
更新:
想也许namespace-alias 可以做点什么,但不知道如何使用它。试过这个,但似乎对输出没有任何影响:
<stylesheet version="2.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:out="http://api.example.com">
<namespace-alias stylesheet-prefix="out" result-prefix=""/>
<template match="/">
<element name="out:moo">
<!-- and so on -->
namespace-alias 的事情可能没有按照我的想法做:p
我使用的最终解决方案,基于 JLRishe 的回答
remove-prefixes.xsl
<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<template match="/">
<variable name="result">
<next-match />
</variable>
<apply-templates select="$result" mode="remove-prefixes" />
</template>
<template match="*" priority="1" mode="remove-prefixes">
<element name="{local-name()}" namespace="{namespace-uri()}">
<apply-templates select="@* | node()" mode="remove-prefixes" />
</element>
</template>
<template match="@*|node()" mode="remove-prefixes">
<copy>
<apply-templates select="@* | node()" mode="remove-prefixes" />
</copy>
</template>
</stylesheet>
subject.xsl
<!-- snip -->
<import href="remove-prefixes.xsl" />
<!-- snip -->
【问题讨论】:
-
关于您的更新和
namespace-alias- 您的示例可能实现的唯一事情是moo被写为http://www.w3.org/1999/XSL/Transform命名空间中。我从来没有尝试过使用空前缀,我不确定这是否真的是namespace-alias的有效用法(尚未检查)。 -
似乎您也可以使用
#default作为namespace-alias属性的值。似乎仍然没有像我希望的那样做...... -
我将在几秒钟内添加一个编辑,这可能会满足您的需求...试试看。
-
我不建议丢失“xsl:”前缀。更好的是,使用良好的代码格式。命名空间的唯一目的是消除歧义。在使用两个不同的词汇表时,隐藏前缀通常会导致混淆——这正是你的情况。通常,源 XML 文档可能具有元素名称,例如“输出”、“元素”、“属性”、“变量”。在这种情况下,如果去掉 :xsl:" 前缀,就很难区分哪个是源 xml 文档,哪个是 XSLT 样式表。可能会出现烦人且耗时的错误。
-
@Svish,我非常尊重您的个人喜好。但是,如果此代码不仅是为了您的眼睛,那么如果您保留“xsl:”前缀不变,其他人都会更容易阅读。另一个重要因素是,某些 XSLT IDE 仅在使用前缀“xsl:”时才进行语法高亮——即使使用了另一个前缀(例如“xslt:”),它们也会停止这样做。
标签: xml xslt xml-namespaces