Преобразование UML-XMI в XML с использованием XSLT
Я пытаюсь преобразовать файл.UML (в формате XMI) в файл XML, написав код xslt. Я новичок в этом и был бы рад, если бы вы могли помочь мне лучше понять. В настоящее время я только пытаюсь прочитать 1 или 2 элемента ввода и распечатать вывод XML с этими элементами.
Входной файл XMI-UML
<?xml version="1.0" encoding="UTF-8"?>
<uml:Model xmi:version="20110701" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" xmlns:uml="http://www.eclipse.org/uml2/4.0.0/UML" xmi:id="_OlYJkC9-EeWyX7UKkcyxiw" name="model">
<packagedElement xmi:type="uml:Activity" xmi:id="_OlYJkS9-EeWyX7UKkcyxiw" name="Activity1" node="_XjLyEC9-EeWyX7UKkcyxiw _ZfIhYC9-EeWyX7UKkcyxiw _cK4V8C9-EeWyX7UKkcyxiw _fE2zwC9-EeWyX7UKkcyxiw _F67sgC9_EeWyX7UKkcyxiw">
<edge xmi:type="uml:ControlFlow" xmi:id="_jzMLIC9-EeWyX7UKkcyxiw" name="ControlFlow" source="_XjLyEC9-EeWyX7UKkcyxiw" target="_ZfIhYC9-EeWyX7UKkcyxiw"/>
<edge xmi:type="uml:ControlFlow" xmi:id="_lieXcC9-EeWyX7UKkcyxiw" name="ControlFlow1" source="_ZfIhYC9-EeWyX7UKkcyxiw" target="_cK4V8C9-EeWyX7UKkcyxiw"/>
<node xmi:type="uml:InitialNode" xmi:id="_XjLyEC9-EeWyX7UKkcyxiw" name="Start" outgoing="_jzMLIC9-EeWyX7UKkcyxiw"/>
<node xmi:type="uml:OpaqueAction" xmi:id="_ZfIhYC9-EeWyX7UKkcyxiw" name="Load and Enable Timer" visibility="package" outgoing="_lieXcC9-EeWyX7UKkcyxiw" incoming="_jzMLIC9-EeWyX7UKkcyxiw"/>
<inputValue xmi:type="uml:ActionInputPin" xmi:id="_82lIMDRBEeWdiarL2UAMaQ" name="interrupt">
<upperBound xmi:type="uml:LiteralInteger" xmi:id="_82lIMTRBEeWdiarL2UAMaQ" value="1"/>
</inputValue>
</node>
<node xmi:type="uml:ActivityFinalNode" xmi:id="_F67sgC9_EeWyX7UKkcyxiw" name="ActivityFinalNode" incoming="_Hcj3UC9_EeWyX7UKkcyxiw"/>
</packagedElement>
</uml:Model>
Код XSLT
<xsl:stylesheet version="1.0" xmlns:UML="org.omg.xmi.namespace.UML" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<root>
<xsl:apply-templates />
</root>
</xsl:template>
<xsl:template match="/uml:Model/packagedElement/edge/">
<xsl:element name="uml:ControlFlow">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
Ожидаемый результат (только пример. Он также может содержать "узел" из ввода)
<?xml version='1.0' encoding='UTF-8'?>
<sdf3 type='sadf' version='1.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='uri:sadf' xsi:schemaLocation='some_random_location'>
<sadf name='RandomGraphName'>
<structure>
<edge name='ControlFlow1' source='_ZfIhYC9-EeWyX7UKkcyxiw' target='_cK4V8C9-EeWyX7UKkcyxiw' />
</structure>
</sadf>
</sdf3>
1 ответ
Судя по всему, "UML-XMI" по-прежнему является документом XML, но, как уже упоминалось в комментариях, он не является правильно сформированным. Проблема с этим node
элемент
<node xmi:type="uml:OpaqueAction" xmi:id="_ZfIhYC9-EeWyX7UKkcyxiw" name="Load and Enable Timer" visibility="package" outgoing="_lieXcC9-EeWyX7UKkcyxiw" incoming="_jzMLIC9-EeWyX7UKkcyxiw"/>
<inputValue xmi:type="uml:ActionInputPin" xmi:id="_82lIMDRBEeWdiarL2UAMaQ" name="interrupt">
<upperBound xmi:type="uml:LiteralInteger" xmi:id="_82lIMTRBEeWdiarL2UAMaQ" value="1"/>
</inputValue>
</node>
Если вы прокрутите вправо, node
тег самозакрывающийся (т.е. заканчивается />
), это означает закрытие </node>
тег на самом деле ничего не соответствует.
Но при условии, что он был правильно сформирован, первая проблема с вашим XSLT связана с пространствами имен. В вашем XML пространство имен определяется следующим образом:
xmlns:uml="http://www.eclipse.org/uml2/4.0.0/UML"
Но в вашем XSLT вы определили это так
xmlns:UML="org.omg.xmi.namespace.UML"
Префикс не обязательно должен совпадать между XML и XSLT, но URI пространства имен делает это. Кроме того, если ваш XSLT при использовании префикса пространства имен, вы используете его в нижнем регистре
<xsl:template match="/uml:Model/packagedElement/edge/">
Это с учетом регистра, так что uml
не будет соответствовать UML
который вы определили. Префикс не обязательно должен соответствовать XML, но он должен совпадать с определенным в XSLT.
Кроме того, это совпадение шаблона также не является синтаксически правильным, поскольку оно заканчивается /
условное обозначение. Это должно быть удалено.
Хотя я не совсем понимаю, какой вывод вы на самом деле хотите, попробуйте этот XSLT, чтобы получить ваш путь:
<xsl:stylesheet version="1.0" xmlns:UML="http://www.eclipse.org/uml2/4.0.0/UML" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns='uri:sadf' exclude-result-prefixes="UML">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/UML:Model">
<sdf3 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='some_random_location' type='sadf'>
<sadf name='RandomGraphName'>
<xsl:apply-templates />
</sadf>
</sdf3>
</xsl:template>
<xsl:template match="packagedElement">
<structure>
<xsl:apply-templates select="edge" />
</structure>
</xsl:template>
<xsl:template match="edge">
<edge name="{@name}" source="{@source}" />
</xsl:template>
</xsl:stylesheet>
Обратите внимание на использование пространства имен по умолчанию в XSLT xmlns='uri:sadf'
, Это означает, что все элементы, которые не имеют пространства имен, будут выводиться в этом пространстве имен.
Также обратите внимание, что вам не обязательно кодировать полный путь к дочерним элементам, таким как packagedElement
а также edge
,
Но учитывая следующий правильно сформированный вклад:
<uml:Model xmi:version="20110701" xmlns:xmi="http://www.omg.org/spec/XMI/20110701" xmlns:uml="http://www.eclipse.org/uml2/4.0.0/UML" xmi:id="_OlYJkC9-EeWyX7UKkcyxiw" name="model">
<packagedElement xmi:type="uml:Activity" xmi:id="_OlYJkS9-EeWyX7UKkcyxiw" name="Activity1" node="_XjLyEC9-EeWyX7UKkcyxiw _ZfIhYC9-EeWyX7UKkcyxiw _cK4V8C9-EeWyX7UKkcyxiw _fE2zwC9-EeWyX7UKkcyxiw _F67sgC9_EeWyX7UKkcyxiw">
<edge xmi:type="uml:ControlFlow" xmi:id="_jzMLIC9-EeWyX7UKkcyxiw" name="ControlFlow" source="_XjLyEC9-EeWyX7UKkcyxiw" target="_ZfIhYC9-EeWyX7UKkcyxiw"/>
<edge xmi:type="uml:ControlFlow" xmi:id="_lieXcC9-EeWyX7UKkcyxiw" name="ControlFlow1" source="_ZfIhYC9-EeWyX7UKkcyxiw" target="_cK4V8C9-EeWyX7UKkcyxiw"/>
<node xmi:type="uml:InitialNode" xmi:id="_XjLyEC9-EeWyX7UKkcyxiw" name="Start" outgoing="_jzMLIC9-EeWyX7UKkcyxiw"/>
<node xmi:type="uml:OpaqueAction" xmi:id="_ZfIhYC9-EeWyX7UKkcyxiw" name="Load and Enable Timer" visibility="package" outgoing="_lieXcC9-EeWyX7UKkcyxiw" incoming="_jzMLIC9-EeWyX7UKkcyxiw">
<inputValue xmi:type="uml:ActionInputPin" xmi:id="_82lIMDRBEeWdiarL2UAMaQ" name="interrupt">
<upperBound xmi:type="uml:LiteralInteger" xmi:id="_82lIMTRBEeWdiarL2UAMaQ" value="1"/>
</inputValue>
</node>
<node xmi:type="uml:ActivityFinalNode" xmi:id="_F67sgC9_EeWyX7UKkcyxiw" name="ActivityFinalNode" incoming="_Hcj3UC9_EeWyX7UKkcyxiw"/>
</packagedElement>
</uml:Model>
Следующий вывод
<sdf3 xmlns="uri:sadf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="some_random_location"
type="sadf">
<sadf name="RandomGraphName">
<structure>
<edge name="ControlFlow" source="_XjLyEC9-EeWyX7UKkcyxiw"/>
<edge name="ControlFlow1" source="_ZfIhYC9-EeWyX7UKkcyxiw"/>
</structure>
</sadf>
</sdf3>