需要以下逻辑方面的帮助。
源XML--
<?xml version="1.0" encoding="UTF-8"?>
<multimap:Messages xmlns:multimap="http://somenamespace.com/xi/XI/SplitAndMerge">
<multimap:Message1>
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<ns0:children_level1 xmlns:ns0="http://mynamespace.com">
<Somedata/>
</ns0:children_level1>
</ns0:ToBeRoot>
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<ns0:children_level2 xmlns:ns0="http://mynamespace.com">
<Somedata/>
</ns0:children_level2>
</ns0:ToBeRoot>
</multimap:Message1>
</multimap:Messages>
目标XML(必需(
<?xml version="1.0" encoding="UTF-8"?>
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<ns0:children_level1 xmlns:ns0="http://mynamespace.com">
<Somedata/>
</ns0:children_level1>
<ns0:children_level2 xmlns:ns0="http://mynamespace.com">
<Somedata/>
</ns0:children_level2>
</ns0:ToBeRoot>
XSLT我试过了,
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://somenamespace.com/xi/XI/SplitAndMerge">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- template for the document element -->
<xsl:template match="/*">
<xsl:apply-templates select="node()/node()/node()"/>
</xsl:template>
<xsl:template match="ToBeRoot">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我认为需要在模板中添加一些内容<xsl:template-match="ToBeRoot">但是正在挣扎,请帮帮我。
使用上述XSLT 的输出
<?xml version="1.0" encoding="UTF-8"?>
<ns0:children_level1 xmlns:ns0="http://mynamespace.com" xmlns:multimap="http://somenamespace.com/xi/XI/SplitAndMerge">
<Somedata/>
</ns0:children_level1>
<ns0:children_level2 xmlns:ns0="http://mynamespace.com" xmlns:multimap="http://somenamespace.com/xi/XI/SplitAndMerge">
<Somedata/>
</ns0:children_level2>
最简单的方法是:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<xsl:copy-of select="*/*/*"/>
</ns0:ToBeRoot>
</xsl:template>
</xsl:stylesheet>
这在复制的元素上留下了一个冗余的命名空间声明,这应该是无害的。如果你想删除它,那么你必须重新创建元素,而不是复制它们:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<xsl:apply-templates select="*/*/*"/>
</ns0:ToBeRoot>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
或者,如果您的处理器支持它:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/*">
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<xsl:copy-of select="*/*/*" copy-namespaces="no"/>
</ns0:ToBeRoot>
</xsl:template>
</xsl:stylesheet>
添加:
从有效载荷中动态获取名称ns0:ToBeRoot是否可行
是。代替:
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<!-- ... -->
</ns0:ToBeRoot>
用途:
<xsl:element name="{name(*/*[1])}" namespace="{namespace-uri(*/*[1])}">
<!-- ... -->
</xsl:element>
听起来好像你想要
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://mynamespace.com"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="*/*/ns0:ToBeRoot[1]"/>
</xsl:template>
<xsl:template match="ns0:ToBeRoot">
<xsl:copy>
<xsl:apply-templates select="node() | following-sibling::ns0:ToBeRoot/node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者更好的XSLT2或3:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://mynamespace.com"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="*/*/ns0:ToBeRoot[1]"/>
</xsl:template>
<xsl:template match="ns0:ToBeRoot">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node() | following-sibling::ns0:ToBeRoot/node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您的命名空间声明中出现了一些混乱:xmlns:ns0
是";http://mynamespace.com"在您的XML中;http://somenamespace.com/xi/XI/SplitAndMerge"在XSLT中。
同步它们将得到以下XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://mynamespace.com" xmlns:multimap="http://somenamespace.com/xi/XI/SplitAndMerge">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<!-- template for the document element -->
<xsl:template match="/multimap:Messages">
<xsl:element name="ns0:ToBeRoot" namespace="http://mynamespace.com">
<xsl:apply-templates select="multimap:Message1/ns0:ToBeRoot/ns0:*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它会给你想要的输出:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:ToBeRoot xmlns:ns0="http://mynamespace.com">
<ns0:children_level1>
<Somedata/>
</ns0:children_level1>
<ns0:children_level2>
<Somedata/>
</ns0:children_level2>
</ns0:ToBeRoot>