Xml 如果在XSLT中
我从XML文件中提取一些数据时遇到问题。如果一个Xml 如果在XSLT中,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我从XML文件中提取一些数据时遇到问题。如果一个ph:Element有多个属性,但输出应该是(s_rel0=5,par_rel0=5)而不是(s_rel0=5)(par_rel0=5),那么我仍然无法理解如何处理ph:Element的属性。也许是一个“如果-那么”的案例 第二个连接应包括法兰b,而不是法兰a。我找了半天,没找到那个错误 你知道我哪里做错了吗!? 谢谢你的帮助 XML: 输出应类似于(s_rel0=5,par_s_rel0=5) 关于括号,只需向相关模板添加/附加一些条件: <
ph:Element
有多个属性,但输出应该是(s_rel0=5,par_rel0=5)
而不是(s_rel0=5)(par_rel0=5)
,那么我仍然无法理解如何处理ph:Element的属性。也许是一个“如果-那么”的案例
第二个连接应包括法兰b
,而不是法兰a
。我找了半天,没找到那个错误
你知道我哪里做错了吗!?
谢谢你的帮助
XML:
输出应类似于(s_rel0=5,par_s_rel0=5)
关于括号,只需向相关模板添加/附加一些条件:
<xsl:template match="ph:Element/ph:Attribute">
<xsl:if test="count(preceding-sibling::*[1][local-name()='Attribute'])=0">
<xsl:text>(</xsl:text>
</xsl:if>
<!-- xsl:choose -->
<xsl:if test="count(following-sibling::*[1][local-name()='Attribute'])=0">
<xsl:text>)</xsl:text>
</xsl:if>
<xsl:if test="count(following-sibling::*[1][local-name()='Attribute'])=1">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:template>
这是因为:
//ph:Element[ph:Port[@id = $sourceid]]
您正在选择整个ph:Element
节点,因此之后需要重新匹配。事实上,你的填塞器在第一次连接时起作用只是一个例子 下面是如何在xslt中使用if-else
<xsl:choose>
<xsl:when test="@ordered=1">
<ol>
<xsl:apply-templates select="item-ordered" />
</ol>
</xsl:when>
<xsl:otherwise>
<ul>
<xsl:apply-templates select="item-unordered" />
</ul>
</xsl:otherwise>
</xsl:choose>
模型
方程式
结束
;
组件。
;
(
=
,
=
)
连接(
.
,
.
);
在我看来,好的XSLT代码没有if/else结构。
以下是仅基于模板覆盖的版本:
<?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="http://www.merge.something.com">
<xsl:output indent="yes" method="text"/>
<xsl:key name="ports" match="//ph:Element/ph:Port" use="@id" />
<xsl:template match="/">
<xsl:apply-templates select="ph:Graphs/ph:Graph"/>
<xsl:text> </xsl:text><!-- new line -->
</xsl:template>
<xsl:template match="ph:Graph">
<xsl:text>model </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> </xsl:text><!-- new line -->
<xsl:apply-templates select="ph:Element"/>
<xsl:text>equation</xsl:text>
<xsl:text> </xsl:text><!-- new line -->
<xsl:apply-templates select="ph:Edge"/>
<xsl:text>end </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>;</xsl:text>
</xsl:template>
<!-- ph:Element with at least one ph:Attribute child -->
<xsl:template match="ph:Element[ph:Attribute]">
<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:text>(</xsl:text>
<xsl:apply-templates select="ph:Attribute"/>
<xsl:text>)</xsl:text>
<xsl:text>; </xsl:text>
</xsl:template>
<!-- ph:Element by default -->
<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>
<!-- Port/Attribute elements are rendered as : "type.value" -->
<xsl:template match="ph:Port/ph:Attribute">
<xsl:apply-templates select="ph:AttributeField[@name='type']" />
<xsl:text>.</xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- First element attribute is rendered as : "name = value" -->
<xsl:template match="ph:Element/ph:Attribute">
<xsl:apply-templates select="ph:AttributeField[@name='name']" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- Other element attributes are rendered as : ", name = value" -->
<xsl:template match="ph:Element/ph:Attribute[position() > 1]">
<xsl:text>, </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='name']" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- By default, an AttributeField is rendered by displaying its "value" attribute -->
<xsl:template match="ph:AttributeField">
<xsl:value-of select="@value" />
</xsl:template>
<!-- "type" AttributeFields are not displayed -->
<xsl:template match="ph:AttributeField[@name='type']" />
<!-- "value" AttributeField whose "type" brother says that it's a 'string' are rendered with single quotes (but only for ph:Element not for ph:Port)-->
<xsl:template match="ph:Element/ph:Attribute/ph:AttributeField[@name='value'][../ph:AttributeField[@name='type']/@value = 'string']">
<xsl:text>'</xsl:text>
<xsl:value-of select="@value" />
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="ph:Port">
<xsl:value-of select="translate(../@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:value-of select="../@id" />
<xsl:apply-templates select="ph:Attribute" />
</xsl:template>
<xsl:template match="ph:Edge">
<xsl:variable name="SourceElement" select="key('ports', @sourceid)"/>
<xsl:variable name="TargetElement" select="key('ports', @targetid)"/>
<xsl:text> connect(</xsl:text>
<xsl:apply-templates select="$SourceElement" />
<xsl:text>, </xsl:text>
<xsl:apply-templates select="$TargetElement" />
<xsl:text >);</xsl:text>
<xsl:text> </xsl:text><!-- new line -->
</xsl:template>
</xsl:stylesheet>
模型
方程式
结束
;
组件。
(
)
;
组件。
;
.
=
,
=
'
'
连接(
,
);
顺便说一下。。。我添加了一个xsl:key元素来索引ph:Port,与//ph:element[ph:Port[@id=$sourceid]]]
count(前面的兄弟姐妹::*[1][local-name()='Attribute'])=0相比,它可以节省处理时间。
写得更漂亮,因为不是(前面的兄弟姐妹姐妹::*[1]/self ph:Attribute)
请标记您认为正确的答案。
<xsl:value-of select="$SourceElement/
ph:Port[@id=$sourceid]/
ph:Attribute/ph:AttributeField[@name = 'value']/@value" />
<xsl:value-of select="$TargetElement/
ph:Port[@id=$targetid]/
ph:Attribute/ph:AttributeField[@name = 'value']/@value" />
//ph:Element[ph:Port[@id = $sourceid]]
<xsl:choose>
<xsl:when test="@ordered=1">
<ol>
<xsl:apply-templates select="item-ordered" />
</ol>
</xsl:when>
<xsl:otherwise>
<ul>
<xsl:apply-templates select="item-unordered" />
</ul>
</xsl:otherwise>
</xsl:choose>
<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: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:Attribute">
<xsl:variable name="count">
<xsl:for-each select=".">
<xsl:if test="ph:AttributeField[@name='type' and @value='int']">
<xsl:value-of select="count(../ph:Attribute)"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="position()<$count">
<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:otherwise>
<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:otherwise>
</xsl:choose>
</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:variable name="SourcePort" select="../ph:Element/ph:Port[@id = $sourceid]"/>
<xsl:variable name="TargetPort" 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="$SourcePort/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="$TargetPort/ph:Attribute/ph:AttributeField[@name = 'value']/@value" />
<xsl:text >);</xsl:text>
</xsl:template>
</xsl:stylesheet>
<?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="http://www.merge.something.com">
<xsl:output indent="yes" method="text"/>
<xsl:key name="ports" match="//ph:Element/ph:Port" use="@id" />
<xsl:template match="/">
<xsl:apply-templates select="ph:Graphs/ph:Graph"/>
<xsl:text> </xsl:text><!-- new line -->
</xsl:template>
<xsl:template match="ph:Graph">
<xsl:text>model </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text> </xsl:text><!-- new line -->
<xsl:apply-templates select="ph:Element"/>
<xsl:text>equation</xsl:text>
<xsl:text> </xsl:text><!-- new line -->
<xsl:apply-templates select="ph:Edge"/>
<xsl:text>end </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>;</xsl:text>
</xsl:template>
<!-- ph:Element with at least one ph:Attribute child -->
<xsl:template match="ph:Element[ph:Attribute]">
<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:text>(</xsl:text>
<xsl:apply-templates select="ph:Attribute"/>
<xsl:text>)</xsl:text>
<xsl:text>; </xsl:text>
</xsl:template>
<!-- ph:Element by default -->
<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>
<!-- Port/Attribute elements are rendered as : "type.value" -->
<xsl:template match="ph:Port/ph:Attribute">
<xsl:apply-templates select="ph:AttributeField[@name='type']" />
<xsl:text>.</xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- First element attribute is rendered as : "name = value" -->
<xsl:template match="ph:Element/ph:Attribute">
<xsl:apply-templates select="ph:AttributeField[@name='name']" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- Other element attributes are rendered as : ", name = value" -->
<xsl:template match="ph:Element/ph:Attribute[position() > 1]">
<xsl:text>, </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='name']" />
<xsl:text> = </xsl:text>
<xsl:apply-templates select="ph:AttributeField[@name='value']" />
</xsl:template>
<!-- By default, an AttributeField is rendered by displaying its "value" attribute -->
<xsl:template match="ph:AttributeField">
<xsl:value-of select="@value" />
</xsl:template>
<!-- "type" AttributeFields are not displayed -->
<xsl:template match="ph:AttributeField[@name='type']" />
<!-- "value" AttributeField whose "type" brother says that it's a 'string' are rendered with single quotes (but only for ph:Element not for ph:Port)-->
<xsl:template match="ph:Element/ph:Attribute/ph:AttributeField[@name='value'][../ph:AttributeField[@name='type']/@value = 'string']">
<xsl:text>'</xsl:text>
<xsl:value-of select="@value" />
<xsl:text>'</xsl:text>
</xsl:template>
<xsl:template match="ph:Port">
<xsl:value-of select="translate(../@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" />
<xsl:value-of select="../@id" />
<xsl:apply-templates select="ph:Attribute" />
</xsl:template>
<xsl:template match="ph:Edge">
<xsl:variable name="SourceElement" select="key('ports', @sourceid)"/>
<xsl:variable name="TargetElement" select="key('ports', @targetid)"/>
<xsl:text> connect(</xsl:text>
<xsl:apply-templates select="$SourceElement" />
<xsl:text>, </xsl:text>
<xsl:apply-templates select="$TargetElement" />
<xsl:text >);</xsl:text>
<xsl:text> </xsl:text><!-- new line -->
</xsl:template>
</xsl:stylesheet>