[英]Append namespace in XSL transformation
I have following XML input:我有以下 XML 输入:
<my_value>test123</my_value>
Here is XSL这是 XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="array fn map math xhtml xs err" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="*">
<xsl:element name="my_node">
<xsl:namespace name="tns" select="'http://www.example.com'"/>
<xsl:element name="my_child">
<xsl:value-of select="my_value"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
As an output I want to have:作为我想要的输出:
<tns:my_node xmlns:tns="http://www.example.com">
<tns:my_child>test123</tns:my_child>
</tns:my_node>
How to modify XSL to achieve my goal?如何修改 XSL 以实现我的目标?
You're making life much too complicated here and you're getting some things wrong.你让这里的生活变得太复杂了,而且你做错了一些事情。
<xsl:template match="my_value">
<xsl:element name="my_node">
<xsl:namespace name="tns" select="'http://www.example.com'"/>
<xsl:element name="my_child">
<xsl:value-of select="my_value"/>
</xsl:element>
</xsl:element>
</xsl:template>
Firstly, xsl:namespace
is only needed if you want to inject a namespace that isn't used in any element or attribute names.首先,只有当您想注入一个未在任何元素或属性名称中使用的命名空间时,才需要
xsl:namespace
。 When you're creating elements and attributes you need to say what namespace they're in, and the namespace nodes/declarations will then be created automatically.当您创建元素和属性时,您需要说明它们所在的命名空间,然后将自动创建命名空间节点/声明。
Secondly, the context node for the template is the my_value element so you get its value using .
其次,模板的上下文节点是 my_value 元素,因此您可以使用
.
, not using my_value
. ,不使用
my_value
。 Context is everything.语境就是一切。
So you could write:所以你可以写:
<xsl:template match="*">
<xsl:element name="tns:my_node" namespace="http://www.example.com"/>
<xsl:element name="my_child" namespace="http://www.example.com">
<xsl:value-of select="."/>
</xsl:element>
</xsl:element>
</xsl:template>
But xsl:element
is needed only when the name of the element you're constructing isn't known statically.但是
xsl:element
仅当您正在构造的元素的名称不是静态已知时才需要。 When the name is fixed, it's much better to use a literal result element:名称固定后,最好使用文字结果元素:
<xsl:template match="*">
<tns:my_node xmlns:tns="http://www.example.com"/>
<tns:my_child>
<xsl:value-of select="."/>
</tns:my_child>
</tns:my_node>
</xsl:template>
Finally with XSLT 3.0 if you set the expand-text="yes" option you can simplify this further to:最后使用 XSLT 3.0,如果您设置 expand-text="yes" 选项,您可以进一步将其简化为:
<xsl:template match="*">
<tns:my_node xmlns:tns="http://www.example.com"/>
<tns:my_child>{.}</tns:my_child>
</tns:my_node>
</xsl:template>
A simple use of literal result elements should suffice:简单地使用文字结果元素就足够了:
<xsl:template match="my_value">
<tns:my_node xmlns:tns="http://www.example.com">
<tns:my_child>
<xsl:value-of select="."/>
</tns:my_child>
</tns:my_node>
</xsl:template>
As you seem to be using XSLT 3 you could also use a text value template instead of xsl:value-of
:由于您似乎在使用 XSLT 3,您还可以使用文本值模板而不是
xsl:value-of
:
<xsl:template match="my_value" expand-text="yes">
<tns:my_node xmlns:tns="http://www.example.com">
<tns:my_child>{.}</tns:my_child>
</tns:my_node>
</xsl:template>
Not sure I got the whole intent, but could you try this:不确定我是否理解了整个意图,但你能试试这个吗:
<xsl:stylesheet xmlns:tns="http://www.example.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="array fn map math xhtml xs err" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="*">
<xsl:element name="tns:my_node">
<xsl:element name="tns:my_child">
<xsl:value-of select="."/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
So, we did the following amends:所以,我们做了以下修改:
xmlns:tns="http://www.example.com"
attribute to the xsl:stylesheet
root element instead of dedicated xsl:namespace
tagxmlns:tns="http://www.example.com"
属性引入xsl:stylesheet
根元素,而不是专用的xsl:namespace
标记my_node
and my_child
right in place (now it's legit because we introduced the prefix)my_node
和my_child
就地(现在它是合法的,因为我们引入了前缀)"."
"."
instead of my_value
my_value
As a result, we have:结果,我们有:
<tns:my_node xmlns:tns="http://www.example.com">
<tns:my_child>test123</tns:my_child>
</tns:my_node>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.