所以我是xslt的新手,使用它2周后,现在遇到了将命名空间和属性从一个节点复制到另一个节点的问题。 我需要将名称空间和属性复制到另一个节点,删除根节点并删除一些不在新节点中的节点。第二部分删除节点可以在其他转换中完成,如果它更容易,我认为应该是。
这是输入文件:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1">
<mode>
<node0>0</node0>
<node1 attribute2="some2">
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</node1>
</mode>
<extra1 id="1"/>
<extra2 id="3"/>
<xmi:XMI>
我需要的输出:
<?xml version="1.0" encoding="UTF-8"?>
<node1 xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" attribute2="some2" >
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</node1>
<extra1 id="1"/>
可能以后需要保留xmi:XMI节点只删除除node1和extra1之外的其他节点,但认为这个带有修改的xsl会有所帮助:
<xsl:stylesheet
xmlns:xls="http://www.w3.org/1999/XSL/Transform"
xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
我现在没有想法如何实现这一目标。任何帮助表示赞赏。
答案 0 :(得分:1)
这是一个示例XSLT 2.0样式表,主要工作不是复制命名空间(默认情况下是这样),主要工作是从extra1
(和潜在的后代)中删除命名空间,我这样做不同模式:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
exclude-result-prefixes="namespace1 xmi">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="xmi:XMI/mode/node1"/>
<xsl:apply-templates select="xmi:XMI/extra1" mode="strip-namespaces"/>
</xsl:template>
<xsl:template match="node1">
<xsl:copy>
<xsl:apply-templates select="@*, /*/@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()" mode="strip-namespaces">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates mode="strip-namespaces"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输入为
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1">
<mode>
<node0>0</node0>
<node1 attribute2="some2">
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</node1>
</mode>
<extra1 id="1"/>
<extra2 id="3"/>
</xmi:XMI>
Saxon 9.4的输出是
<?xml version="1.0" encoding="UTF-8"?><node1 xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute2="some2" attribute1="some1">
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</node1><extra1 id="1"/>
答案 1 :(得分:0)
该脚本工作表示感谢。但今天我的任务改变了一点:( 对不起,第一个问题不是最终要求:(
现在我需要做类似的事情:
1)节点可以使用命名空间,我现在不知道节点的位置, 可以是namespace1:mode / node0 / namespace1:parm,但可以是namespace1:mode / node0 /../ namespace1:parm 或namespace1:mode / node0 /../ element或类似但需要按类型和名称查找节点, 其中namespace1:type =“type1”和name =“givenName”
2)可能是不同的节点需要成为根节点,例如namespace1:parm或element,但必须每次都有标签namespace1:parm。 首先,我需要不删除xmi节点,如果有使用的节点则不需要合并属性。
3)命名空间每次都可以不同,现在不用如何使这项工作。需要删除未使用的标签。
4)可能需要另一个转换,但是当xmi:XMI和namespace1:parm格式化标签在xmi:XMI标签中没有extar标签时,需要将xmi:XMI与namespace1:parm合并并保留所有属性和命名空间。
输入:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" xmlns:M="mOptions" xmlns:N="nOptions">
<namespace1:mode name="Main">
<node0>0</node0>
<namespace1:parm name="node1" attribute2="some2" namespace1:type="type1">
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</namespace1:parm>
<element name="node2" attribute2="some3" namespace1:type="type2">
<child6 name="a6" id="6"/>
<child7 name="b7" id="7"/>
</element>
<node id="55"/>
</namespace1:mode>
<M:extra1 id="1"/>
<M:extra2 id="2"/>
<M:extra6 id="6"/>
<M:extra7 id="7"/>
</xmi:XMI>
我需要与上次相似的第一个可能性,需要找到名称空间的所有内容。试图修改xsl,没有成功。 需要的输出: 当namespace1:type =“type1”
时<?xml version="1.0" encoding="UTF-8"?>
<namespace1:parm name="node1" attribute2="some2" namespace1:type="type1">
<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</namespace1:parm>
<M:extra1 id="1"/>
<M:extra2 id="2"/>
当namespace1:type =“type2”
时<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" xmlns:M="mOptions" xmlns:N="nOptions">
<namespace1:parm name="node2" attribute2="some3" namespace1:type="type2">
<child6 name="a6" id="6"/>
<child7 name="b7" id="7"/>
</namespace1:parm>
<M:extra6 id="6"/>
<M:extra7 id="7"/>
</xmi:XMI>
如果:
<namespace1:parm name="node2" attribute2="some3" namespace1:type="type2">
<child6 name="a6" id="6"/>
<child7 name="b7" id="7"/>
</namespace1:parm>
</xmi:XMI>
然后需要
<?xml version="1.0" encoding="UTF-8"?>
<namespace1:parm name="node2" attribute2="some3" namespace1:type="type2"xmlns:namespace1="http://namespace" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" attribute1="some1" xmlns:M="mOptions" xmlns:N="nOptions">
<child6 name="a6" id="6"/>
<child7 name="b7" id="7"/>
</namespace1:parm>
试过:
<xsl:template match="*">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="xmi:XMI|*[@namespace1:type='type1']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xmi:XMI|*[@namespace1:type='type1']">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:attribute name="{name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
但是得到:
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:namespace1="http://namespace"
xmlns:xmi="http://www.omg.org/spec/XMI/20110701"
xmlns:M="mOptions"
xmlns:N="nOptions"
attribute1="some1">some1<namespace1:mode name="Main">
<namespace1:parm name="node1" attribute2="some2" namespace1:type="type1">node1some2type1<child1 name="a" id="1"/>
<child2 name="b" id="2"/>
</namespace1:parm>
</namespace1:mode>
<M:extra1 id="1"/>
<M:extra2 id="3"/>
<M:extra6 id="6"/>
<M:extra7 id="7"/>
</xmi:XMI>