假设我的XML文件中有以下代码,我想在行中显示以下信息:creationDate - serviceName - problemCode - division。
<foi:serviceInfo rdf:ID="SI1">
<foi:serviceName>Sewer</foi:serviceName>
<foi:problemCode>SI1</foi:problemCode>
<foi:division>Water</foi:division>
</foi:serviceInfo>
<foi:serviceInfo rdf:ID="SI2">
<foi:serviceName>Recycling</foi:serviceName>
<foi:problemCode>SI2</foi:problemCode>
<foi:division>Solid Waste</foi:division>
</foi:serviceInfo>
<foi:serviceRequest rdf:ID="R1">
<foi:creationDate>29 03 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI1"/>
</foi:serviceRequest>
<foi:serviceRequest rdf:ID="R2">
<foi:creationDate>29 06 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI2"/>
</foi:serviceRequest>
我能够在行中显示来自serviceRequest的信息,但是,我不知道如何将foi:service中的资源链接到serviceInfo的ID(为了获取serviceInfo中包含的属性,然后显示它)。
答案 0 :(得分:1)
这是一个不太优雅的解决方案,需要额外的工作来扩展到结构不同的数据集(尽管它适用于样本数据集中排列的任意数量的serviceInfo和serviceRequest元素)。它的优点是它涉及使用apply-templates而不是for-each。使用apply-templates是最佳实践。另外,我不知道使用正确的命名空间,所以我只是做了一些。
此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foi="http://www.foi.com"
xmlns:rdf="http://www.rdf.com"
exclude-result-prefixes="foi rdf"
version="2.0">
<!-- Identity template -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="newLine"><xsl:text>
</xsl:text></xsl:variable>
<xsl:template match="/">
<xsl:value-of select="$newLine"/><table><xsl:value-of select="$newLine"/>
<xsl:apply-templates select="//foi:creationDate"/>
</table><xsl:value-of select="$newLine"/>
</xsl:template>
<xsl:template match="foi:creationDate">
<xsl:variable name="resourceId" select="replace(../foi:servicing/@rdf:resource,'#','')"/>
<xsl:message>BAH <xsl:value-of select="$resourceId"/></xsl:message>
<tr><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:serviceName[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:problemCode[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:division[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
</tr><xsl:value-of select="$newLine"/>
</xsl:template>
<xsl:template match="foi:serviceName">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="foi:problemCode">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="foi:division">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:(注意:我添加了根元素)
<root>
<foi:serviceInfo rdf:ID="SI1">
<foi:serviceName>Sewer</foi:serviceName>
<foi:problemCode>SI1</foi:problemCode>
<foi:division>Water</foi:division>
</foi:serviceInfo>
<foi:serviceInfo rdf:ID="SI2">
<foi:serviceName>Recycling</foi:serviceName>
<foi:problemCode>SI2</foi:problemCode>
<foi:division>Solid Waste</foi:division>
</foi:serviceInfo>
<foi:serviceRequest rdf:ID="R1">
<foi:creationDate>29 03 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI1"/>
</foi:serviceRequest>
<foi:serviceRequest rdf:ID="R2">
<foi:creationDate>29 06 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI2"/>
</foi:serviceRequest>
</root>
产生所需的结果:
<tr>
<td>29 03 2013</td>
<td>Sewer</td>
<td>SI1</td>
<td>Water</td>
</tr>
<tr>
<td>29 06 2013</td>
<td>Recycling</td>
<td>SI2</td>
<td>Solid Waste</td>
</tr>
</table>
简要说明:
答案 1 :(得分:1)
这个较短的转换使用了一个用于X参考的键,并在表格中生成了想要的结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foi="some:foi" xmlns:rdf="some:rdf" exclude-result-prefixes="foi rdf">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kSIById" match="foi:serviceInfo" use="concat('#',@rdf:ID)"/>
<xsl:template match="/*">
<table border="1"><xsl:apply-templates/></table>
</xsl:template>
<xsl:template match="/*/*" priority="-1"/>
<xsl:template match="/*/foi:serviceRequest">
<tr>
<td><xsl:apply-templates select="foi:creationDate"/></td>
<xsl:apply-templates select="key('kSIById', foi:servicing/@rdf:resource)/*"/>
</tr>
</xsl:template>
<xsl:template match="foi:serviceInfo/*">
<td><xsl:value-of select="."/></td>
</xsl:template>
</xsl:stylesheet>
应用于提供的源XML(包含在单个顶部元素中并且定义了名称空间):
<root xmlns:foi="some:foi" xmlns:rdf="some:rdf">
<foi:serviceInfo rdf:ID="SI1">
<foi:serviceName>Sewer</foi:serviceName>
<foi:problemCode>SI1</foi:problemCode>
<foi:division>Water</foi:division>
</foi:serviceInfo>
<foi:serviceInfo rdf:ID="SI2">
<foi:serviceName>Recycling</foi:serviceName>
<foi:problemCode>SI2</foi:problemCode>
<foi:division>Solid Waste</foi:division>
</foi:serviceInfo>
<foi:serviceRequest rdf:ID="R1">
<foi:creationDate>29 03 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI1"/>
</foi:serviceRequest>
<foi:serviceRequest rdf:ID="R2">
<foi:creationDate>29 06 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI2"/>
</foi:serviceRequest>
</root>
会产生想要的正确结果:
<table border="1">
<tr>
<td>29 03 2013</td>
<td>Sewer</td>
<td>SI1</td>
<td>Water</td>
</tr>
<tr>
<td>29 06 2013</td>
<td>Recycling</td>
<td>SI2</td>
<td>Solid Waste</td>
</tr>
</table>
答案 2 :(得分:0)
在XSLT中交叉引用数据的首选方法是使用<xsl:key>
。以下XSLT应该这样做:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foi="foifoifoi" xmlns:rdf="rdfrdf"
exclude-result-prefixes="foi rdf">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kService" match="foi:serviceInfo" use="@rdf:ID"/>
<xsl:template match="/*">
<div>
<xsl:apply-templates select="foi:serviceRequest" />
</div>
</xsl:template>
<xsl:template match="foi:serviceRequest">
<xsl:variable name="referenceId"
select="substring(foi:servicing/@rdf:resource, 2)" />
<xsl:variable name="info" select="key('kService', $referenceId)[1]"/>
<div>
<xsl:value-of select="foi:creationDate"/>
<xsl:apply-templates select="$info/*" />
</div>
</xsl:template>
<xsl:template match="foi:serviceInfo/*">
<xsl:value-of select="concat(' - ', .)"/>
</xsl:template>
</xsl:stylesheet>
(我必须为foi
和rdf
组成名称空间,因为您没有表明它们。请在正确的URI中替换)。在此XML上运行时(添加了根节点):
<root xmlns:foi="foifoifoi" xmlns:rdf="rdfrdf">
<foi:serviceInfo rdf:ID="SI1">
<foi:serviceName>Sewer</foi:serviceName>
<foi:problemCode>SI1</foi:problemCode>
<foi:division>Water</foi:division>
</foi:serviceInfo>
<foi:serviceInfo rdf:ID="SI2">
<foi:serviceName>Recycling</foi:serviceName>
<foi:problemCode>SI2</foi:problemCode>
<foi:division>Solid Waste</foi:division>
</foi:serviceInfo>
<foi:serviceRequest rdf:ID="R1">
<foi:creationDate>29 03 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI1"/>
</foi:serviceRequest>
<foi:serviceRequest rdf:ID="R2">
<foi:creationDate>29 06 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI2"/>
</foi:serviceRequest>
</root>
这会产生:
<div>
<div>29 03 2013 - Sewer - SI1 - Water</div>
<div>29 06 2013 - Recycling - SI2 - Solid Waste</div>
</div>
要点:
xsl:key
允许按某个foi:serviceInfo
找到ID
。key()
功能按ID查找相关的foi:serviceInfo
。最后的[1]
将此限制为第一场比赛。我不确定是否有可能有多场比赛,但是在那里?foi:serviceInfo
的任何子项作为连字符加上元素值的模板。