我是这个论坛的新手,甚至是xsl的新手。 我需要帮助来解决XML代码的一个小问题:请看一下下面的结构。
*********************************
<ProductRevision id="id45" **************>
<ApplicationRef **************/>
<UserData *********>
<UserValue title="title1" value="11111 000 000"/>
<UserValue title="object_name" value="test name1"/>
</UserData>
</ProductRevision>
<ProductRevision id="id50" ***********>
<ApplicationRef **************/>
<UserData id="id46">
<UserValue title="title1" value="22222 000 000"/>
<UserValue title="object_name" value="test name2"/>
</UserData>
</ProductRevision>
*******************************************
<GeneralRelation id="id49" subType="TestType" relatedRefs="#id2 #id45">
<ApplicationRef **************/>
<UserData ********>
<UserValue title="ds5_amont" type="int" value="3"/>
<UserValue title="ds5_cavities" type="int" value="2"/>
</UserData>
</GeneralRelation>
<GeneralRelation id="id49" subType="TestType" relatedRefs="#id2 #id50">
<ApplicationRef ***********/>
<UserData **********>
<UserValue title="ds5_amont" type="int" value="2"/>
<UserValue title="ds5_cavities" type="int" value="3"/>
</UserData>
</GeneralRelation>
如您所见,ProductRevision节点包含一个id值;此值标识两个对应的GeneralRelation节点,其中包含UserValues ds5_amont 和 ds5_cavities 。 我使用以下.xsl代码片段来显示所有ProductRevision节点的title1和object_name的值:
<xsl:for-each select="//plm:ProductRevision[@subType = 'XXXXX']">
<xsl:variable name="part" select="./plm:UserData/plm:UserValue[@title='object_name']/@value" />
<xsl:variable name="identnr" select="./plm:UserData/plm:UserValue[@title='title1']/@value" />
<Row>
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="$part"/>
</Data>
</Cell>
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="$identnr"/>
</Data>
</Cell>
</Row>
现在,对于每个ProductRevision,我需要显示相应的 ds5_amont 和 ds5_cavities 值,这些值包含在 id45 标识的相应节点中和 id50 值。这些属性必须打印在显示$ part和$ identnr变量的单元格旁边。 到目前为止,我还找不到解决方案,我们将不胜感激! 谢谢!
编辑
对不起,我无法在2秒内学习如何在您的论坛上重现Excel表。结果应该像这样: 对于每个产品版本,应该有一行显示 object_name **** title1 **** ds5_amont **** ds5_cavities 再次抱歉,希望它足够清楚;-)
答案 0 :(得分:1)
使用`00000000 <__ltdf2>:`
` 0: 4e56 0000 linkw %fp,#0`
`4: 4878 0001 pea 1 <__ltdf2+0x1>`
` 8: 2f2e 0014 movel %fp@(20),%sp@-`
` c: 2f2e 0010 movel %fp@(16),%sp@-`
`10: 2f2e 000c movel %fp@(12),%sp@-`
`14: 2f2e 0008 movel %fp@(8),%sp@-`
`18: 61ff 0000 0000 bsrl 1a <__ltdf2+0x1a>`
`1e: 4e5e unlk %fp`
` 20: 4e75 rts`
处理器,您可以利用EXSLT libxslt
扩展功能。
请考虑以下简化示例:
XML
str:tokenize()
XSLT 1.0 + EXSLT
<root>
<ProductRevision id="id45">
<ApplicationRef/>
<UserData>
<UserValue title="title1" value="11111 000 000"/>
<UserValue title="object_name" value="test name1"/>
</UserData>
</ProductRevision>
<ProductRevision id="id50">
<ApplicationRef/>
<UserData id="id46">
<UserValue title="title1" value="22222 000 000"/>
<UserValue title="object_name" value="test name2"/>
</UserData>
</ProductRevision>
<GeneralRelation id="id49" subType="TestType" relatedRefs="#id2 #id45">
<ApplicationRef/>
<UserData>
<UserValue title="ds5_amont" type="int" value="453"/>
<UserValue title="ds5_cavities" type="int" value="452"/>
</UserData>
</GeneralRelation>
<GeneralRelation id="id49" subType="TestType" relatedRefs="#id2 #id50">
<ApplicationRef/>
<UserData>
<UserValue title="ds5_amont" type="int" value="502"/>
<UserValue title="ds5_cavities" type="int" value="503"/>
</UserData>
</GeneralRelation>
</root>
结果
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="relation" match="GeneralRelation" use="str:tokenize(@relatedRefs, ' ')" />
<xsl:template match="/root">
<table>
<xsl:for-each select="ProductRevision">
<Row>
<!-- ProductRevision -->
<Cell>
<xsl:value-of select="UserData/UserValue[@title='object_name']/@value"/>
</Cell>
<Cell>
<xsl:value-of select="UserData/UserValue[@title='title1']/@value"/>
</Cell>
<!-- GeneralRelation -->
<xsl:variable name="relation" select="key('relation', concat('#', @id))" />
<Cell>
<xsl:value-of select="$relation/UserData/UserValue[@title='ds5_amont']/@value"/>
</Cell>
<Cell>
<xsl:value-of select="$relation/UserData/UserValue[@title='ds5_cavities']/@value"/>
</Cell>
</Row>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
您要处理在其GeneralRelation
属性列表中具有当前@id
元素的ProductRevision
值的@relatedRefs
元素。在XSLT 1.0中,您可以使用contains
和current
函数,如下所示:
/root
/GeneralRelation
[contains
(concat(@relatedRefs,' '),
concat('#',current()/@id,' ')
)
]
此输入:
<root>
<ProductRevision id="id45">
<ApplicationRef />
<UserData>
<UserValue title="title1" value="11111 000 000" />
<UserValue title="object_name" value="test name1" />
</UserData>
</ProductRevision>
<ProductRevision id="id50">
<ApplicationRef />
<UserData id="id46">
<UserValue title="title1" value="22222 000 000" />
<UserValue title="object_name" value="test name2" />
</UserData>
</ProductRevision>
<GeneralRelation id="id49" subType="TestType"
relatedRefs="#id2 #id45">
<ApplicationRef />
<UserData>
<UserValue title="ds5_amont" type="int" value="453" />
<UserValue title="ds5_cavities" type="int" value="452" />
</UserData>
</GeneralRelation>
<GeneralRelation id="id49" subType="TestType"
relatedRefs="#id2 #id50">
<ApplicationRef />
<UserData>
<UserValue title="ds5_amont" type="int" value="502" />
<UserValue title="ds5_cavities" type="int" value="503" />
</UserData>
</GeneralRelation>
</root>
这种转变
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:variable name="vGeneralRelation"
select="/root/GeneralRelation" />
<xsl:template match="text()|GeneralRelation" />
<xsl:template match="root">
<table>
<xsl:apply-templates />
</table>
</xsl:template>
<xsl:template match="ProductRevision">
<Row>
<xsl:apply-templates
select="*|$vGeneralRelation[
contains(concat(@relatedRefs,' '),
concat('#',current()/@id,' '))]/*" />
</Row>
</xsl:template>
<xsl:template
match="UserValue[@title[.='object_name' or .='title1' or .='ds5_cavities' or .='ds5_amont']]">
<Cell>
<xsl:value-of select="@value" />
</Cell>
</xsl:template>
</xsl:stylesheet>
产生此输出
<?xml version="1.0" encoding="utf-8"?>
<table>
<Row>
<Cell>11111 000 000</Cell>
<Cell>test name1</Cell>
<Cell>453</Cell>
<Cell>452</Cell>
</Row>
<Row>
<Cell>22222 000 000</Cell>
<Cell>test name2</Cell>
<Cell>502</Cell>
<Cell>503</Cell>
</Row>
</table>
在http://xsltransform.net/6qaFCEU上查看工作示例
答案 2 :(得分:0)
谢谢大家的贡献。 最后,这是我使用的解决方案。我猜您的解决方案都是非常复杂且专业的解决方案,但是对于像我这样的初学者来说,有必要简化代码,以便甚至可以轻松识别错误。 但我可以告诉您,我将对这些解决方案进行大量研究! 首先,通过 subType 属性识别正确的 ProductRevision 节点;然后,在ProductRevision节点的上下文中显示两个变量,并将ID存储在 pid 变量中:
<xsl:template match="//plm:ProductRevision[@subType='DS5_PartRevision']">
<xsl:variable name="part" select="./plm:UserData/plm:UserValue[@title='object_name']/@value" />
<xsl:variable name="identnr" select="./plm:UserData/plm:UserValue[@title='ds5_s_serien_identnr']/@value" />
<xsl:variable name="pid" select="@id"/>
<Row>
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="$part"/>
</Data>
</Cell>
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="$identnr"/>
</Data>
</Cell>
处理完第一个ProductRevision节点后,检查所有 GeneralRelation 节点;为每个节点创建变量 relref ,并存储 relatedRefs 属性值的一部分。仅存储“#”(空格-#)之后的值:
<xsl:for-each select="/plm:PLMXML/plm:GeneralRelation">
<xsl:variable name="relref" select="substring-after(@relatedRefs,' #')"/>
<xsl:choose>
<xsl:when test="$relref=$pid">
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="./plm:UserData/plm:UserValue[@title='ds5_amont']/@value"/>
</Data>
</Cell>
<Cell ss:StyleID="s73">
<Data ss:Type="String">
<xsl:value-of select="./plm:UserData/plm:UserValue[@title='ds5_cavities']/@value"/>
</Data>
</Cell>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</Row>
对于每个GeneralRelation节点,比较 pid 和 relref 的值:如果它们匹配,则在GeneralRelation的上下文中获取两个属性的值节点(因此使用./plm/表示法),并将其显示在(相应ProductRevision的)正确的行中。