【问题标题】:xslt extract node and remove certain attributesxslt 提取节点并删除某些属性
【发布时间】:2018-06-26 14:04:06
【问题描述】:

我正在尝试从 XMI 模型文档中提取 UML 配置文件定义,然后使用 XSLT 删除不需要/非法的属性

源 XMI 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xmi:XMI xmlns:uml="http://www.omg.org/spec/UML/20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:umldi="http://www.omg.org/spec/UML/20131001/UMLDI" xmlns:dc="http://www.omg.org/spec/UML/20131001/UMLDC" xmlns:thecustomprofile="http://www.sparxsystems.com/profiles/thecustomprofile/1.0" xmlns:Plusprofil="http://www.sparxsystems.com/profiles/Plusprofil/0.9.1">
<uml:Model xmi:type="uml:Model" name="EA_Model">
<...>

</uml:Model>
<xmi:Extension extender="Enterprise Architect" extenderID="6.5">
<...>
    <profiles>
            <uml:Profile xmlns:uml="http://www.omg.org/spec/UML/20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmi:id="FF44B996-D" nsPrefix="Plusprofil" name="Plusprofil" metamodelReference="mmref01">

                <packagedElement xmi:type="uml:Extension" xmi:id="Property_RdfsProperty" name="A_Property_RdfsProperty" memberEnd="extension_RdfsProperty RdfsProperty-base_Property">
                <ownedEnd xmi:id="extension_RdfsProperty" name="extension_RdfsProperty" type="RdfsProperty" isComposite="true" lower="0" upper="1" memberEnd="extension_RdfsProperty RdfsProperty-base_Property"/>
            </packagedElement>
<...>
        </uml:Profile>
    </profiles>
</xmi:Extension>

</xmi:XMI>

预期的输出看起来像这样 - 模型的配置文件部分,删除了属性 nsPrefix、lower、upper 和 isComposite:

<?xml version="1.0" encoding="utf-8"?>
<uml:Profile xmlns:uml="http://www.omg.org/spec/UML/20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmi:id="FF44B996-D" name="Plusprofil" metamodelReference="mmref01">
<packagedElement xmi:type="uml:Extension" xmi:id="Property_RdfsProperty" name="A_Property_RdfsProperty" memberEnd="extension_RdfsProperty RdfsProperty-base_Property">
<ownedEnd xmi:id="extension_RdfsProperty" name="extension_RdfsProperty" type="RdfsProperty" memberEnd="extension_RdfsProperty RdfsProperty-base_Property"/>
</packagedElement>
<...>
</uml:Profile>

我可以使用 copy-of 轻松提取配置文件部分,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.omg.org/spec/UML/20131001">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/" >
<xsl:copy-of select="/xmi:XMI/xmi:Extension/profiles/uml:Profile[@name='Plusprofil']" >
</xsl:copy-of>
</xsl:template>
</xsl:stylesheet>

我可以使用生成的文件,在另一个样式表中使用身份转换模式来删除属性:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.omg.org/spec/UML/20131001">
<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>
<xsl:template match="@nsPrefix"/>
<xsl:template match="@memberEnd"/>
<xsl:template match="ownedEnd/@lower[../@lower='0']"/>
<xsl:template match="ownedEnd/@upper[../@upper='1']"/>
<xsl:template match="ownedEnd/@isComposite[../@isComposite='true']"/>
</xsl:stylesheet>

但是我如何将这两项工作结合到一个文件中呢? 我认为,这会起作用,但它不会删除非法属性:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.omg.org/spec/UML/20131001">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/" >
    <xsl:copy-of select="/xmi:XMI/xmi:Extension/profiles/uml:Profile[@name='Plusprofil']" >
        <xsl:call-template name="modify" select="@* | node()"/>  
    </xsl:copy-of>
</xsl:template>
<xsl:template name="modify" match="@* | node()" >
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>  
    </xsl:copy>
 </xsl:template>
<xsl:template match="@nsPrefix"/>
<xsl:template match="@memberEnd"/>
<xsl:template match="ownedEnd/@lower[../@lower='0']"/>
<xsl:template match="ownedEnd/@upper[../@upper='1']"/>
<xsl:template match="ownedEnd/@isComposite[../@isComposite='true']"/>
</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt attributes profile xmi


    【解决方案1】:

    如果在与/ 匹配的主模板中使用xsl:copy-of(这不起作用,因为您不能在其中嵌套任何其他xslt 命令),请使用xsl:apply-templates

    <xsl:template match="/" >
        <xsl:apply-templates select="xmi:XMI/xmi:Extension/profiles/uml:Profile[@name='Plusprofil']" />
    </xsl:template>
    

    这样既可以使用身份模板,也可以使用您的覆盖模板之一(如果它们匹配)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-11
      • 2017-07-11
      • 1970-01-01
      • 2011-10-07
      • 2019-09-26
      • 2017-01-20
      • 1970-01-01
      相关资源
      最近更新 更多