Hey guys,

I have a problem extracting some data out of this XML file:

<?xml version="1.0" encoding="UTF-8"?>
<ph:Graphs xmlns:ph="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<ph:Graph name="mass_spring_mo">
		<ph:Element id="0" type="Fixed">
			<ph:Port id="1" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Element id="2" type="Spring">
			<ph:Attribute>
				<ph:AttributeField name="type" value="int"/>
				<ph:AttributeField name="name" value="s_rel0"/>
				<ph:AttributeField name="value" value="5"/>
			</ph:Attribute>
			<ph:Attribute>
				<ph:AttributeField name="type" value="int"/>
				<ph:AttributeField name="name" value="par_s_rel0"/>
				<ph:AttributeField name="value" value="5"/>
			</ph:Attribute>
			<ph:Port id="3" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_a"/>
				</ph:Attribute>
			</ph:Port>
			<ph:Port id="4" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_b"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Element id="5" type="Mass">
			<ph:Port id="6" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_a"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Edge id="7" sourceid="1" targetid="3"/>
		<ph:Edge id="8" sourceid="4" targetid="6"/>
	</ph:Graph>
</ph:Graphs>

This is the solution I found. I still have problems to figure out how to handle the <attributes> of a ph:Element if there are more than one but the output should look like (s_rel0 = 10, par_s_rel0 = 5) and not like (s_rel0 = 5)(par_s_rel0 = 5).

And the second conection should consist of flange_b and not of flange_a. I searched for while the mistake but could not find it.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ph="">

    <xsl:output indent="yes" method="text"/>

    <xsl:template match="/">
            <xsl:apply-templates select="ph:Graphs/ph:Graph"/>
    </xsl:template>

    <xsl:template match="ph:Graph">
        <xsl:text>model </xsl:text><xsl:value-of select="@name"/><xsl:text>
</xsl:text>
        <xsl:apply-templates select="ph:Element"/>
        <xsl:text>equation
</xsl:text>
        <xsl:apply-templates select="ph:Edge"/>
        <xsl:text>end </xsl:text><xsl:value-of select="@name"/><xsl:text>;</xsl:text>
    </xsl:template>

    <xsl:template match="ph:Element">
        <xsl:text> Components.</xsl:text><xsl:value-of select="@type"/><xsl:text > </xsl:text>
        <xsl:value-of select="translate(@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/><xsl:value-of select="@id"/>
        <xsl:apply-templates select="ph:Attribute"/>
        <xsl:text>;
</xsl:text>
    </xsl:template>

    <xsl:template match="ph:Element/ph:Attribute">
        <xsl:choose>
           <xsl:when test="ph:AttributeField[@name = 'type' and @value='int']">
              <xsl:text>(</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'name']/@value"/><xsl:text> = </xsl:text><xsl:value-of select="ph:AttributeField[@name = 'value']/@value" /><xsl:text>)</xsl:text>
           </xsl:when>
           <xsl:when test="ph:AttributeField[@name = 'type' and @value='string']">
              <xsl:text>(</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'name']/@value"/><xsl:text> = '</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'value']/@value" /><xsl:text>')</xsl:text>
           </xsl:when>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="ph:Port/ph:Attribute">
        <xsl:if test="ph:AttributeField/@value=type">
            <xsl:apply-templates select="ph:AttributeField"/>
        </xsl:if>
    </xsl:template>

    <xsl:template match="ph:AttributeField">
    </xsl:template>

    <xsl:template match="ph:Edge">
        <xsl:variable name="sourceid" select="@sourceid"/>
        <xsl:variable name="targetid" select="@targetid"/>
        <xsl:variable name="SourceElement" select="//ph:Element[ph:Port[@id = $sourceid]]"/>
        <xsl:variable name="TargetElement" select="//ph:Element[ph:Port[@id = $targetid]]"/>
        <xsl:text> connect(</xsl:text>
        <xsl:value-of select="translate($SourceElement/@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
        <xsl:value-of select="$SourceElement/@id" />
        <xsl:text>.</xsl:text>
        <xsl:value-of select="$SourceElement/ph:Port/ph:Attribute/ph:AttributeField[@name = 'value']/@value" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="translate($TargetElement/@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
        <xsl:value-of select="$TargetElement/@id" />
        <xsl:text>.</xsl:text>
        <xsl:value-of select="$TargetElement/ph:Port/ph:Attribute/ph:AttributeField[@name = 'value']/@value" />
        <xsl:text >);
</xsl:text>
    </xsl:template>

</xsl:stylesheet>

The disired output should look like this:

model mass_spring_mo
 Components.Fixed fixed1;
 Components.Spring spring2(s_rel0 = 10, par_s_rel0 = 5);
 Components.Mass mass5;
equation  
 connect(fixed1.flange,spring2.flange_a);
 connect(spring2.flange_b,mass5.flange_a);
end mass_spring_mo;

Thanks in advance.
Michael

Dani AI

Generated

Two short, practical fixes: group an element’s multiple ph:Attribute entries into one parenthesised, comma-separated list, and select the specific ph:Port by its @id when building the connect(...) call. correctly spotted that the mysterious “10” wasn’t in the XML and confirmed it should be 5.

The grouping problem happens because a template fires for each ph:Attribute and prints its own parentheses. Instead, have the ph:Element template collect the attribute nodes and emit a single parenthesis block with a comma before every item except the first. Example pattern (XSLT 1.0):

<xsl:variable name="attrs" select="ph:Attribute[ph:AttributeField[@name='type']]"/>
<xsl:if test="$attrs">
  <xsl:text>(</xsl:text>
  <xsl:for-each select="$attrs">
    <xsl:if test="position() &gt; 1"><xsl:text>, </xsl:text></xsl:if>
    <xsl:choose>
      <xsl:when test="ph:AttributeField[@name='type' and @value='int']">
        <xsl:value-of select="ph:AttributeField[@name='name']/@value"/>
        <xsl:text> = </xsl:text>
        <xsl:value-of select="ph:AttributeField[@name='value']/@value"/>
      </xsl:when>
      <xsl:when test="ph:AttributeField[@name='type' and @value='string']">
        <xsl:value-of select="ph:AttributeField[@name='name']/@value"/>
        <xsl:text> = '</xsl:text>
        <xsl:value-of select="ph:AttributeField[@name='value']/@value"/>
        <xsl:text>'</xsl:text>
      </xsl:when>
    </xsl:choose>
  </xsl:for-each>
  <xsl:text>)</xsl:text>
</xsl:if>

For the wrong flange selection: your code was finding the element that contains a port and then taking the first port value. Instead select the exact port by id (either from the element or directly). Example:

<xsl:variable name="sourceid" select="@sourceid"/>
<xsl:variable name="srcPort" select="//ph:Port[@id = $sourceid]"/>
<xsl:value-of select="$srcPort/ph:Attribute/ph:AttributeField[@name='value']/@value"/>

Quick checklist: (1) do the comma-join inside ph:Element (remove/disable the per-attribute template that prints its own parentheses); (2) always filter ph:Port by @id when you need that port’s data; (3) remember value-of returns the first node’s string-value, so predicates matter. These two changes will produce the single “(a, b)” attribute block and the correct flange names for each connection.

Recommended Answers

All 2 Replies

is in the xml xsl transformation found no error
where should come from the 10 in the xml is to find a 10 and it will not be charged


in der xml xsl umwandlung ist kein fehler zu finden
wo soll die 10 herkommen in der xml ist kein 10 zu finden und berechnet wird sie auch nicht

<?xml version="1.0" encoding="UTF-8"?>
<ph:Graphs xmlns:ph="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<ph:Graph name="mass_spring_mo">
		<ph:Element id="0" type="Fixed">
			<ph:Port id="1" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Element id="2" type="Spring">
			<ph:Attribute>
				<ph:AttributeField name="type" value="int"/>
				<ph:AttributeField name="name" value="s_rel0"/>
				<ph:AttributeField name="value" value="5"/>
			</ph:Attribute>
			<ph:Attribute>
				<ph:AttributeField name="type" value="int"/>
				<ph:AttributeField name="name" value="par_s_rel0"/>
				<ph:AttributeField name="value" value="5"/>
			</ph:Attribute>
			<ph:Port id="3" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_a"/>
				</ph:Attribute>
			</ph:Port>
			<ph:Port id="4" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_b"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Element id="5" type="Mass">
			<ph:Port id="6" type="port">
				<ph:Attribute>
					<ph:AttributeField name="type" value="string"/>
					<ph:AttributeField name="name" value="type"/>
					<ph:AttributeField name="value" value="flange_a"/>
				</ph:Attribute>
			</ph:Port>
		</ph:Element>
		<ph:Edge id="7" sourceid="1" targetid="3"/>
		<ph:Edge id="8" sourceid="4" targetid="6"/>
	</ph:Graph>
</ph:Graphs>

Oh, that was my mistake. It should be a 5 of course.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.