0

所以我是 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>

我现在不知道如何做到这一点。任何帮助表示赞赏。

4

2 回答 2

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"/>
于 2012-05-29T17:40:34.070 回答
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 标签中只有 xmi:XMI 和 namespace1:parm 格式的标签且没有 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>
于 2012-05-30T07:14:36.990 回答