我有一个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的回答
除去-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 -->
答案 0 :(得分:3)
您可以做的一件事是在变量中捕获XSL的整个结果,然后在结尾处删除其前缀:
<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:p="http://api.example.com">
<output method="xml" indent="yes"/>
<template match="/">
<variable name="result">
<p:moo>
<apply-templates />
</p:moo>
</variable>
<apply-templates select="$result" mode="removePrefix" />
</template>
<template match="root">
<p:something hello="hi">
<element name="p:somethingelse" />
</p:something>
</template>
<template match="p:*" mode="removePrefix">
<element name="{local-name()}" namespace="{namespace-uri()}">
<apply-templates select="@* | node()" mode="removePrefix" />
</element>
</template>
<template match="@* | node()" mode="removePrefix">
<copy>
<apply-templates select="@* | node()" />
</copy>
</template>
</stylesheet>
在此输入上运行时:
<root>
<top />
</root>
它产生:
<moo xmlns="http://api.example.com">
<something hello="hi">
<somethingelse />
</something>
</moo>
答案 1 :(得分:1)
xmlns:xsl
- 方法实际上是“标准”日,我认为XSL的设计者考虑到了这一点。
请记住,您可以直接将XML片段混合到XSL中。从这个角度来看,使用xsl:element
的方法可以说比使用“element-default-namespace”消除的噪音和混乱更多。
所以,我会这样做:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://api.example.com">
<xsl:template match="/">
<moo>
<!-- and so on -->
修改强>
以下namespace-alias
可能有效:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://api.example.com">
<namespace-alias stylesheet-prefix="xsl" result-prefix="#default"/>
<template match="/" xmlns="http://www.w3.org/1999/XSL/Transform">
<element name="moo">
<!-- etc -->
或者像这样:
<stylesheet version="2.0"
exclude-result-prefixes="api"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:api="http://api.example.com">
<namespace-alias stylesheet-prefix="#default" result-prefix="api"/>
<template match="/">
<element name="moo">
<!-- etc -->
答案 2 :(得分:0)
我对你的混乱感觉和你一样,特别是如果我有样式表,绝大多数元素都在XSL命名空间中,而不是在目标命名空间中。解决方案很简单:为输出元素提供前缀而不是XSL元素:
<stylesheet version="2.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:o="http://api.example.com">
<template match="/">
<o:moo>
<!-- and so on -->