使用XSLT添加其他名称空间
我需要在已经有名称空间的XML文件中添加一个额外的名称空间,但前提是特定元素不存在 我的XML文档看起来像:使用XSLT添加其他名称空间,xslt,namespaces,Xslt,Namespaces,我需要在已经有名称空间的XML文件中添加一个额外的名称空间,但前提是特定元素不存在 我的XML文档看起来像: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp"> <common>Stuff Here</common> &l
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<ns3:firstname>Billy</ns3:firstname>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" xmlns:frog="FFF" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<frog:title>
<Master/>
</frog:title>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Copy Everything -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="ns:{local-name()}">
<xsl:attribute name="frog">fff</xsl:attribute>
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这里的东西
比利
鲍比
。。。如果person元素中没有ns3:firstname元素,我想在person中添加一个新的名称空间和(例如xmlns:frog=“FFF”),并添加一个额外的元素,如下所示:
所需输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<ns3:firstname>Billy</ns3:firstname>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" xmlns:frog="FFF" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<frog:title>
<Master/>
</frog:title>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Copy Everything -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="ns:{local-name()}">
<xsl:attribute name="frog">fff</xsl:attribute>
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这里的东西
鲍比
我的XSL文档当前为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<ns3:firstname>Billy</ns3:firstname>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<everyone xmlns="AAA" xmlns:ns2="BBB" xmlns:ns3="CCC" xmlns:frog="FFF" company="TestingCorp">
<common>Stuff Here</common>
<ns2:person id="123">
<frog:title>
<Master/>
</frog:title>
<ns2:lastname>Bobby</ns2:lastname>
</ns2:person>
</everyone>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Copy Everything -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="ns:{local-name()}">
<xsl:attribute name="frog">fff</xsl:attribute>
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
fff
。。。。不幸的是,这不起作用
我尝试了很多不同的方法,但似乎无法使用XSLT v1.0实现这一点。非常感谢您的帮助。首先,您需要在样式表中声明各种名称空间,以及
“AAA”
默认名称空间
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="AAA"
xmlns:frog="FFF"
xmlns:ns2="BBB"
xmlns:ns3="CCC">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Copy Everything -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- for a Person with no firstname, add a frog:title -->
<xsl:template match="ns2:person[not(ns3:firstname)]">
<xsl:copy>
<!-- must handle attributes before elements/text nodes -->
<xsl:apply-templates select="@*" />
<frog:title>
<Master/>
</frog:title>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
复制样式表元素的名称空间声明(尽管这意味着每个输出文档都有一个xmlns:frog
声明,即使它不涉及任何frog:
元素)
编辑:显然Xalan不喜欢
文档(“”)
中的名称空间的副本,作为替代,如果您知道document元素将始终具有相同的名称,则可以将其硬编码为文字结果元素
<xsl:template match="/*">
<everyone xmlns:frog="FFF">
<xsl:copy-of select="namespace::*" />
<xsl:apply-templates select="@*|node()" />
</everyone>
</xsl:template>
(从技术上讲,即使在这个模板中没有显式的xmlns:frog
,它也可以做您想要做的事情,因为文字结果元素总是在样式表中声明名称空间的点上得到名称空间声明,但是如果包含它,其意图可以说更清楚)
对文档(“”)
无法正常工作的原因提供了一些可能的见解。感谢您的快速响应。我还没有对此进行测试,但从我对XSLT的有限知识来看,如果person中缺少ns3:firstname元素,我看不出这将如何只添加frog:title元素。@user211994诀窍在于match=“ns2:person[not(ns3:firstname)]”
-此模板仅适用于没有名字的person
元素,那些有名字的元素将使用标识模板。嗨,还有,有没有办法通过只指定要添加到根元素的新名称空间并复制所有现有名称空间来实现这一点,不必指定所有其他的吗?@user211994它就是这么做的。xsl:stylesheet
上的xmlns:ns2
和xmlns:ns3
是使模板匹配表达式有效所必需的,而xmlns=
是将生成的Master
元素放入正确的命名空间中。如果在模板中使用
而不是
,则可以不使用默认名称空间,但ns2和NS3绝对是必需的。我刚刚尝试了这一点,它完全按照您所说的那样工作-非常感谢。