2013-02-02 25 views
0

说我在我的XML文件中有下面的代码,我想在行中显示以下信息:creationDate - serviceName - problemCode - division。从链接数据中获取属性XSLT

<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行中的信息,我不知道如何在政府信息公开资源链接:维修工作serviceInfo(的ID,以获得在包含在serviceInfo属性,并随后显示它)。

回答

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> 

(我不得不作出了命名空间foirdf因为你没有说明他们请正确的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:serviceInfoID
  • 使用key()函数按ID查找相关foi:serviceInfo。最后的[1]限制了第一场比赛。我不确定是否有可能会有不止一场比赛,但在那里?
  • 用于将foi:serviceInfo的任何子项作为连字符加上元素值的模板。
+0

非常感谢JL。这工作得很好。在这种情况下,可以有多个与serviceInfo关联的serviceRequest。 – user2035965

+0

我看到,所以多个serviceRequest可以引用同一个serviceInfo,但每个serviceRequest只引用一个serviceInfo(换句话说,serviceRequest-> serviceInfo是多个 - >一个)? – JLRishe

+0

是的,这是正确的。再次感谢 – user2035965

1

这是一个不雅的解决方案,需要额外的工作来扩展到结构不同的数据集(尽管它适用于安排在您的示例数据集中的任意数量的serviceInfo和serviceRequest元素)。它的优点是它涉及使用apply-templates而不是for-each。使用应用程序模板是最佳实践。另外,我不知道使用正确的命名空间,所以我只是做了一些。

这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> 

的简要说明:

  • 禁止文本节点(文本节点的默认模板是输出他们。我们将在结束时的XSLT文件的 )
  • 过程FOI输出它们通过特定的模板:creationDate元件
  • 当处理每个FOI:CREATEDATE元件查找其父的rdf:资源并将该值存储在变量中
  • 然后处理每个适当的元素,通过查看文档中的每个元素(这是“//”的意思)中的所有元素找到,其父元素的rdf:ID 与rdf:resource相匹配(注意:如果 存在多个值符合条件的元素...您的数据集 没有这样的多个元素; *可能[也许应该] foi:serviceName,但我想显示什么意思 - 选择任何 元素和[]中的东西可区分哪些元素可以 合格)
  • 这还允许您在serviceName等元素中拥有子节点(除文本节点之外)已经处理过了(虽然现在处理正在复制到结果树中)
+0

非常感谢这个详细的解决方案。 – user2035965

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>