(XML版本=" 1.0")我对XSLT很陌生。我得到了以下XML:
<SNAPSHOTS>
<SNAPSHOT>
<ID>1</ID>
<STATUS>COM</STATUS>
</SNAPSHOT>
<SNAPSHOT>
<ID>2</ID>
<STATUS>ACC</STATUS>
</SNAPSHOT>
</SNAPSHOTS>
根据我的要求,我设法将提供的XML转换为包含在<DC>
根元素中,并在<SNAPSHOTS>
元素之前包含标题。
<?xml version="1.0" encoding="utf-8"?>
<DC>
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords>2</NoOfRecords>
</Header>
<SNAPSHOTS>
<SNAPSHOT>
<ID>1</ID>
<STATUS>COM</STATUS>
</SNAPSHOT>
<SNAPSHOT>
<ID>2</ID>
<STATUS>ACC</STATUS>
</SNAPSHOT>
</SNAPSHOTS>
<DC>
这是我创建的XSD:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<DC>
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords><xsl:value-of select="count(SNAPSHOTS/SNAPSHOT)"/></NoOfRecords>
</Header>
<xsl:apply-templates select="node()"/>
</DC>
</xsl:template>
<xsl:strip-space elements="*"/>
<xsl:template match="node()" name="removeNode">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当我将命名空间包含到<DC>
时,命名空间也会被复制到节点。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<DC xmlns="http://TEST/TEST.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"> <<-- NAMESPACE ADDED
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords><xsl:value-of select="count(SNAPSHOTS/SNAPSHOT)"/></NoOfRecords>
</Header>
<xsl:apply-templates select="node()"/>
</DC>
输出:
<?xml version="1.0" encoding="utf-8"?>
<DC xmlns="http://TEST/TEST.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords>2</NoOfRecords>
</Header>
<SNAPSHOTS xmlns=""> <<--INCORRECT
<SNAPSHOT>
<ID>1</ID>
<STATUS>COM</STATUS>
</SNAPSHOT>
<SNAPSHOT>
<ID>2</ID>
<STATUS>ACC</STATUS>
</SNAPSHOT>
</SNAPSHOTS>
<DC>
我尝试了很多解决方案(谷歌搜索&#39;没有命名空间的XSLT复制节点&#39;等等)。我试过的方法之一是以下(xsl copy nodes without xmlns),但它没有删除xmlns =&#34;&#34;
<xsl:apply-templates select="*" mode="copy-no-namespaces"/>
<xsl:template match="*" mode="copy-no-namespaces">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()" mode="copy-no-namespaces"/>
</xsl:element>
</xsl:template>
我还阅读了以下内容,但并不完全理解接受的答案。 enter link description here
我一直在研究这个问题已经有好几个小时了,显然有些东西我还没有得到。对不起,如果我错过了一些简单的事情,考虑到以前提出的类似问题!非常感谢您提供的任何帮助!托马斯
答案 0 :(得分:2)
在输入XML中,SNAPSHOTS
节点和所有后代节点不属于任何命名空间。在XSLT中,您要向DC
添加默认命名空间,但是然后从没有命名空间的输入中复制SNAPSHOTS
,因此必须添加xmlns=''
以显示{ {1}}不在任何名称空间中。没有它,这意味着SNAPSHOTS
是您为SNAPSHOTS
添加的默认命名空间的一部分。
现在,假设你想要你的输出:
DC
然后,不是按原样复制<DC xmlns="http://TEST/TEST.xsd">
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords>2</NoOfRecords>
</Header>
<SNAPSHOTS>
<SNAPSHOT>
<ID>1</ID>
<STATUS>COM</STATUS>
</SNAPSHOT>
<SNAPSHOT>
<ID>2</ID>
<STATUS>ACC</STATUS>
</SNAPSHOT>
</SNAPSHOTS>
</DC>
节点,而是创建具有相同本地名称但属于同一名称空间的新节点。
试试这个XSLT
SNAPSHOTS
请注意,<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<DC xmlns="http://TEST/TEST.xsd">
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords><xsl:value-of select="count(SNAPSHOTS/SNAPSHOT)"/></NoOfRecords>
</Header>
<xsl:apply-templates select="node()"/>
</DC>
</xsl:template>
<xsl:template match="*" name="removeNode">
<xsl:element name="{local-name()}" namespace="http://TEST/TEST.xsd">
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
现在是SNAPSHOTS
的一部分,因此与输入中的http://TEST/TEST.xsd
不同,后者不是命名空间的一部分。
另一方面,也许SNAPSHOTS
不应该是命名空间的一部分?在这种情况下,您可以尝试使用名称空间前缀,如下所示:
SNAPSHOTS
这应输出以下内容
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<t:DC xmlns:t="http://TEST/TEST.xsd">
<t:Header>
<t:FileName>TEST.xml</t:FileName>
<t:NoOfRecords><xsl:value-of select="count(SNAPSHOTS/SNAPSHOT)"/></t:NoOfRecords>
</t:Header>
<xsl:apply-templates select="node()"/>
</t:DC>
</xsl:template>
<xsl:template match="node()" name="removeNode">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
问题如下:在一个输出元素(DC
,一个新创建的元素)上声明一个默认命名空间,但不在它内部的元素(SNAPSHOT
等等)上声明默认命名空间,它们是从输入XML中检索)。 XSLT处理器被迫假设您打算在这个默认名称空间中说明内部的元素不。
如果您还在输入XML的其余元素上声明了相同的默认命名空间:
<xsl:template match="*" name="removeNode">
<xsl:element name="{name()}" xmlns="http://TEST/TEST.xsd">
命名空间未声明消失。对我来说,仍然不清楚为什么你需要在DC
元素上声明这两个名称空间。
<强>样式表强>
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<DC xmlns="http://TEST/TEST.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords><xsl:value-of select="count(SNAPSHOTS/SNAPSHOT)"/></NoOfRecords>
</Header>
<xsl:apply-templates select="node()"/>
</DC>
</xsl:template>
<xsl:strip-space elements="*"/>
<xsl:template match="*" name="removeNode">
<xsl:element name="{name()}" xmlns="http://TEST/TEST.xsd">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML输出
<?xml version="1.0" encoding="utf-8"?>
<DC xmlns="http://TEST/TEST.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Header>
<FileName>TEST.xml</FileName>
<NoOfRecords>2</NoOfRecords>
</Header>
<SNAPSHOTS>
<SNAPSHOT>
<ID>1</ID>
<STATUS>COM</STATUS>
</SNAPSHOT>
<SNAPSHOT>
<ID>2</ID>
<STATUS>ACC</STATUS>
</SNAPSHOT>
</SNAPSHOTS>
</DC>