2013-02-02 45 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>