首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XSLT转换后保持XML文件的层次结构(顺序)

使用XSLT转换后保持XML文件的层次结构(顺序)
EN

Stack Overflow用户
提问于 2015-04-24 11:16:23
回答 2查看 253关注 0票数 0

我正在尝试将一个XML文件转换为另一个文件,但在保持输入文件的相同层次结构方面遇到了问题。

以下是输入:

代码语言:javascript
复制
<XMI xmi.version='1.2' xmlns:UML="org.omg.xmi.namespace.UML">
  <XMI.content>
    <UML:Model xmi.id='eee_1045467100313_135436_1' name='Data'>
      <UML:Namespace.ownedElement>
        <UML:Package xmi.id='_9_0_bc102e5_1427365805826_580042_23' name='migration_kbir'>
          <UML:Namespace.ownedElement>
            <UML:Package xmi.id='_9_0_bc102e5_1427365805826_580042_22' name='migration_s8ir'>
              <UML:Package xmi.id='_9_0_bc102e5_1427365805826_580042_22' name='migration_s8ir2'>
                <UML:Class xmi.id='_9_0_bc102e5_1427367042666_255023_151' name='Employee'>
                  <UML:Classifier.feature>
                    <UML:Attribute xmi.id='_9_0_bc102e5_1427367052819_893122_168' name='cin'>
                    </UML:Attribute>
                  </UML:Classifier.feature>
                </UML:Class>
                <UML:Class xmi.id='_9_0_64701d4_1429716452808_363115_43' name='AssoEmpl'>
                </UML:Class>
                <UML:Generalization xmi.id='_9_0_64701d4_1429719509242_100032_198' child='_9_0_64701d4_1429719498101_197360_182' parent='_9_0_64701d4_1429716437842_892182_26' />
              </UML:Package>
            </UML:Package>
          </UML:Namespace.ownedElement>
        </UML:Package>
      </UML:Namespace.ownedElement>
    </UML:Model>
  </XMI.content>
</XMI>

下面是我输出的内容:

代码语言:javascript
复制
<xmi:XMI xmlns:xmi="http://www.omg.org/XMI" xmlns:UML="org.omg.xmi.namespace.UML"
  xmi.version="2.1" timestamp="">
  <packagedElement xmi:type="uml:package"
    xmi.id="_9_0_bc102e5_1427365805826_580042_23" name="migration_kbir" />
  <packagedElement xmi:type="uml:package"
    xmi.id="_9_0_bc102e5_1427365805826_580042_22" name="migration_s8ir" />
  <packagedElement xmi:type="uml:package"
    xmi.id="_9_0_bc102e5_1427365805826_580042_22" name="migration_s8ir2">
    <packagedElement xmi:type="uml:Class"
      xmi.id="_9_0_bc102e5_1427367042666_255023_151" name="Employee">
      <generalization xmi.id="_9_0_bc102e5_1427367042666_255023_151">
        <general xmi:type="uml:Class" />
      </generalization>
      <ownedAttribute xmi.id="_9_0_bc102e5_1427367052819_893122_168"
        name="cin" />
    </packagedElement>
    <packagedElement xmi:type="uml:Class"
      xmi.id="_9_0_64701d4_1429716452808_363115_43" name="AssoEmpl">
      <generalization xmi.id="_9_0_64701d4_1429716452808_363115_43">
        <general xmi:type="uml:Class" />
      </generalization>
    </packagedElement>
  </packagedElement>
</xmi:XMI>

但我期待着这样的事情:

代码语言:javascript
复制
<xmi:XMI xmlns:xmi="http://www.omg.org/XMI" xmlns:UML="org.omg.xmi.namespace.UML" xmi.version="2.1" timestamp="">
  <packagedElement xmi:type="uml:package" xmi.id="_9_0_bc102e5_1427365805826_580042_23" name="migration_kbir">
      <packagedElement xmi:type="uml:package"xmi.id="_9_0_bc102e5_1427365805826_580042_22" name="migration_s8ir">
          <packagedElement xmi:type="uml:package"xmi.id="_9_0_bc102e5_1427365805826_580042_22" name="migration_s8ir2">
              <packagedElement xmi:type="uml:Class"xmi.id="_9_0_bc102e5_1427367042666_255023_151" name="Employee">
                  <generalization xmi.id="_9_0_bc102e5_1427367042666_255023_151">
                    <general xmi:type="uml:Class" />
                  </generalization>
                  <ownedAttribute xmi.id="_9_0_bc102e5_1427367052819_893122_168"name="cin" />
              </packagedElement>
              <packagedElement xmi:type="uml:Class" xmi.id="_9_0_64701d4_1429716452808_363115_43" name="AssoEmpl">
                  <generalization xmi.id="_9_0_64701d4_1429716452808_363115_43">
                    <general xmi:type="uml:Class" />
                  </generalization>
              </packagedElement>
          </packagedElement>
      </packagedElement>
  </packagedElement>
</xmi:XMI>

最后,这里是我的转换文件:

代码语言:javascript
复制
<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:UML="org.omg.xmi.namespace.UML"
  xmlns:xmi="http://www.omg.org/XMI"
>
  <xsl:output indent="yes" method="xml" />

  <xsl:template match="/">
    <xmi:XMI>
      <xsl:attribute name="xmi.version">2.1</xsl:attribute>
      <xsl:attribute name="timestamp">
        <xsl:value-of select="@timestamp" />
      </xsl:attribute>
      <xsl:for-each select="//UML:Package">
        <packagedElement>
          <xsl:attribute name="xmi:type">uml:package</xsl:attribute>
          <xsl:attribute name="xmi.id">
            <xsl:value-of select="@xmi.id" />
          </xsl:attribute>
          <xsl:attribute name="name">
            <xsl:value-of select="@name" />
          </xsl:attribute>
          <xsl:choose>
            <xsl:when test="UML:Class">
              <xsl:for-each select="UML:Class">
                <packagedElement>
                  <xsl:attribute name="xmi:type">uml:Class</xsl:attribute>
                  <xsl:attribute name="xmi.id">
                    <xsl:value-of select="@xmi.id" />
                  </xsl:attribute>
                  <xsl:attribute name="name">
                    <xsl:value-of select="@name" />
                  </xsl:attribute>
                  <generalization>
                    <xsl:attribute name="xmi.id">
                      <xsl:value-of select="@xmi.id" />
                    </xsl:attribute>
                    <general xmi:type="uml:Class" />
                  </generalization>
                  <xsl:for-each select="UML:Classifier.feature/UML:Attribute">
                    <ownedAttribute>
                      <xsl:attribute name="xmi.id">
                        <xsl:value-of select="@xmi.id" />
                      </xsl:attribute>
                      <xsl:attribute name="name">
                        <xsl:value-of select="@name" />
                      </xsl:attribute>
                    </ownedAttribute>
                  </xsl:for-each>
                </packagedElement>
              </xsl:for-each>
            </xsl:when>
          </xsl:choose>
        </packagedElement>
      </xsl:for-each>
    </xmi:XMI>
  </xsl:template>
</xsl:stylesheet>

如何在转换代码中保持输入文件的层次结构?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-24 11:50:16

当你这样做时:

代码语言:javascript
复制
<xsl:for-each select="//UML:Package">

您正在选择文档中的all UML:Package元素、anywhere,并将它们作为兄弟。因为这不是您想要的,所以您需要更改您的方法并递归地应用模板。

我已经对你现有的样式表做了一个快速的调整,看看它是否适用于你:

代码语言:javascript
复制
<xsl:stylesheet xmlns:UML="org.omg.xmi.namespace.UML" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <xmi:XMI xmi.version="2.1">
        <xsl:attribute name="xmi.version">2.1</xsl:attribute>
        <xsl:attribute name="timestamp">
            <xsl:value-of select="@timestamp"/>
        </xsl:attribute>
        <xsl:apply-templates/>  
    </xmi:XMI>  
</xsl:template> 

<xsl:template match="UML:Package">      
    <packagedElement>
      <xsl:attribute name="xmi:type">uml:package</xsl:attribute>
      <xsl:attribute name="xmi.id">
        <xsl:value-of select="@xmi.id"/>
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
      <xsl:choose>
        <xsl:when test="UML:Class">
          <xsl:for-each select="UML:Class">
            <packagedElement>
              <xsl:attribute name="xmi:type">uml:Class</xsl:attribute>
              <xsl:attribute name="xmi.id">
                <xsl:value-of select="@xmi.id"/>
              </xsl:attribute>
              <xsl:attribute name="name">
                <xsl:value-of select="@name"/>
              </xsl:attribute>
              <generalization>
                <xsl:attribute name="xmi.id">
                  <xsl:value-of select="@xmi.id"/>
                </xsl:attribute>
                <general xmi:type="uml:Class"/>
              </generalization>
              <xsl:for-each select="UML:Classifier.feature/UML:Attribute">
                <ownedAttribute>
                  <xsl:attribute name="xmi.id">
                    <xsl:value-of select="@xmi.id"/>
                  </xsl:attribute>
                  <xsl:attribute name="name">
                    <xsl:value-of select="@name"/>
                  </xsl:attribute>
                </ownedAttribute>
              </xsl:for-each>
            </packagedElement>
          </xsl:for-each>
        </xsl:when>
      </xsl:choose>
      <xsl:apply-templates/>  
    </packagedElement>
</xsl:template>

</xsl:stylesheet>

Note

  1. 您应该学习如何直接向文字结果元素添加属性,以及如何使用属性值模板。这可以大大简化样式表。
  2. 这是: > 在没有属性的根节点的上下文中没有任何意义。
票数 1
EN

Stack Overflow用户

发布于 2015-04-24 12:16:08

如果您想要一种推式类型的样式表:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:UML="org.omg.xmi.namespace.UML"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xmi="http://www.omg.org/XMI">

    <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="XMI">
        <xmi:XMI xmlns:xmi="http://www.omg.org/XMI" xmlns:UML="org.omg.xmi.namespace.UML"
            xmi.version="2.1" timestamp="">
            <xsl:apply-templates/>
        </xmi:XMI>
    </xsl:template>

    <xsl:template match="UML:Package">
        <packagedElement xmi:type="umi:package">
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </packagedElement>
    </xsl:template>

    <xsl:template match="UML:Class">
        <packagedElement xmi:type="uml:Class">
            <xsl:copy-of select="@*"/>
            <xsl:choose>
                <xsl:when test="UML:Classifier.feature">
                    <xsl:apply-templates/>
                </xsl:when>
                <xsl:otherwise>
                    <generalization xmi.id="{../@xmi.id}">
                        <general xmi:type="uml:Class" />
                    </generalization>
                </xsl:otherwise>
            </xsl:choose>
        </packagedElement>
    </xsl:template>

    <xsl:template match="UML:Classifier.feature">
        <generalization xmi.id="{../@xmi.id}">
            <general xmi:type="uml:Class" />
        </generalization>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="UML:Attribute">
        <ownedAttribute>
            <xsl:copy-of select="@*"/>
        </ownedAttribute>
    </xsl:template>

    <xsl:template match="XMI.content|UML:Model|UML:Namespace.ownedElement">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="UML:Generalization"/>


</xsl:stylesheet>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29846081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档