2015-04-24 4 views
0

Я пытаюсь преобразовать XML-файл в другой, но у меня проблема с сохранением одинаковой иерархии входного файла.сохранить иерархию (заказ) XML-файла после преобразования с помощью XSLT

Вот вход:

<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> 

Вот что я получаю в качестве выхода:

<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> 

, но я ожидал что-то вроде этого:

<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> 

и, наконец, вот мой файл преобразования:

<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> 

Что мне делать в коде преобразования, чтобы сохранить иерархию моего входного файла?

+0

Пожалуйста переформатировать XSL. Это почти неразборчиво. –

+0

Также ваш желаемый результат: a) плохо сформирован и b) не похож на то, что он очень хорошо вписывается в ваш образец. Пожалуйста, дважды проверьте свой результат. – Tomalak

ответ

1

Когда вы делаете:

<xsl:for-each select="//UML:Package"> 

вы выбираете всеUML:Package элементы, везде в документе, и рассматривать их как братьев и сестер. Поскольку это не то, что вы хотите, вам нужно изменить свой подход и вместо этого применить рекурсивные шаблоны.

Я сделал быструю корректировку существующей styleheet, увидеть, если это работает для вас:

<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> 

Примечание:

  1. Вы должны научиться добавлять атрибуты непосредственно буквальным элементы результата и способ использования шаблона значения атрибута . Это может значительно упростить вашу таблицу стилей.

  2. Это:

    <xsl:attribute name="timestamp"> 
        <xsl:value-of select="@timestamp"/> 
    </xsl:attribute> 
    

    не имеет смысла в контексте корневого узла, который не имеет атрибутов.

+0

Спасибо @ michael.hor257k! – Iheb

1

Если вы хотите толчок стиле типа стилей:

<?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> 
+0

Вы можете удалить ' umi: package' (и т. Д.) В пользу объявления атрибута напрямую. Помимо этого, это в точности то, что я собирался подготовить в качестве ответа. \ * бросает собственный чертеж \ * – Tomalak

+0

@ Томалак, я отредактировал свой ответ. Спасибо. –

Смежные вопросы