我正在编写XSLT脚本,我的目标是在根元素中插入名称空间(http://www.COMP.com/upp/readxml/09)。我写了几个变体,其中的两个代码部分解决了它。
代码AB:
<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:tns="http://www.COMP.com/upp/readxml/09">
<xsl:output method="xml"/>
<xsl:template match="*">
<xsl:variable name="elname">
<xsl:text disable-output-escaping="yes">tns:</xsl:text>
<xsl:value-of select="local-name()"/>
</xsl:variable>
<xsl:element name="tns:{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
代码PQ:
<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:output method="xml"/>
<xsl:template match="*" priority="1">
<xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
<xsl:copy-of copy-namespaces="no" select="*[local-name() != 'RootDocument']"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输入XML:
<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<System Id="GOLD" />
<Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
<Timezone Id="UTC" />
<CorrelationID Id="" />
</Header>
<Channels>
<Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
<ChannelID ID="LC:2A" />
</Channel>
</Channels>
</RootDocument>
期望的输出XML:
<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<System Id="GOLD" />
<Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
<Timezone Id="UTC" />
<CorrelationID Id="" />
</Header>
<Channels>
<Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
<ChannelID ID="LC:2A" />
</Channel>
</Channels>
</RootDocument>
OR
<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09">
<Header>
<System Id="GOLD" />
<Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
<Timezone Id="UTC" />
<CorrelationID Id="" />
</Header>
<Channels>
<Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
<ChannelID ID="LC:2A" />
</Channel>
</Channels>
</RootDocument>
能否请您提出如何以XML或其他任何方式正确插入属性的方法,以便仅在保留其余XML不变的情况下插入名称空间。
答案 0 :(得分:0)
您正在将空名称空间中的元素转换为某些固定名称空间。所以这个样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[namespace-uri()='']">
<xsl:element name="{name()}" namespace="http://www.COMP.com/upp/readxml/09">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出:
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Header>
<System Id="GOLD"/>
<Creation_Datetime Datetime="2019-02-19T17:53:38Z"/>
<Timezone Id="UTC"/>
<CorrelationID Id=""/>
</Header>
<Channels>
<Channel StartDate="2019-01-01T00:00:00-05:00"
EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
<ChannelID ID="LC:2A"/>
</Channel>
</Channels>
</RootDocument>
请注意:自XPath 2.0起,namespace
轴已弃用,这意味着“如果XPath 1.0兼容模式为false,则对名称空间轴的支持是实现定义的” ,因此您可能会获得第二种格式的预期结果。实际上,我只知道一个不能处理namespace
轴的XSLT处理器:Mozilla Firefox内部XSLT处理器,即使它只是一个XSLT 1.0处理器,也将其does not implement the namespace
轴夹在其中。
答案 1 :(得分:0)
您可以使用以下模板来获得所需结果的第二版:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:strip-space elements="*" />
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
<xsl:apply-templates select="node()|@*" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy select="@*" />
</xsl:template>
</xsl:stylesheet>
输出为:
<?xml version="1.0"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09">
<Header>
<System Id="GOLD"/>
<Creation_Datetime Datetime="2019-02-19T17:53:38Z"/>
<Timezone Id="UTC"/>
<CorrelationID Id=""/>
</Header>
<Channels>
<Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
<ChannelID ID="LC:2A"/>
</Channel>
</Channels>
</RootDocument>
答案 2 :(得分:0)
极简主义版本:
XSLT 1.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="us-ascii" standalone="yes" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这将产生您的问题中显示的第二个结果。要获得第一个输出(及其冗余名称空间声明),请更改:
<xsl:copy-of select="@*"/>
收件人:
<xsl:copy-of select="@* | namespace::*"/>
答案 3 :(得分:0)
感谢大家对我的查询的答复。以上所有解决方案都在起作用,同时我也在尝试,这是我开发的,它也提供了预期的结果。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>