使用XSLT输出XML封装的文字

时间:2010-02-27 07:53:33

标签: xml xslt

我想将RDF / XML文件转换为3列的表,即“Subject”“Predicate”和“Object”,这些被称为RDF三元组。

RDF / XML文件如下所示:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:h="http://www.w3.org/1999/xhtml">
  <rdf:Description rdf:about="http://www.w3.org/TR/2004/REC-rdf-mt-20040210/">
    <dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">RDF Semantics - W3C Recommendation 10 February 2004</dc:title>
  </rdf:Description>
  <rdf:Description rdf:about="http://www.w3.org/TR/2004/REC-rdf-mt-20040210/">
    <dc:creator rdf:resource="#a1" xmlns:dc="http://purl.org/dc/elements/1.1/" />
  </rdf:Description>
  <rdf:Description rdf:about="#a1">
    <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person" />
  </rdf:Description>
  <rdf:Description rdf:about="#a1">
    <foaf:name xmlns:foaf="http://xmlns.com/foaf/0.1/">Patrick Hayes</foaf:name>
  </rdf:Description>
  <rdf:Description rdf:about="#a1">
    <foaf:homepage rdf:resource="http://www.ihmc.us/users/user.php?UserID=42" xmlns:foaf="http://xmlns.com/foaf/0.1/" />
  </rdf:Description>
</rdf:RDF>

和我创建的XSLT:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
<xsl:template match="/">
<html>
<body>

  <table border="1">
    <tr bgcolor="#5d7b9d" >
      <th style="color: white">Subject</th>
      <th style="color: white">Predicate</th>
      <th style="color: white">Object</th> 
    </tr>


    <xsl:for-each select="rdf:RDF/rdf:Description">
    <tr>

      <td><xsl:value-of select="@rdf:about"/></td>

 <xsl:for-each select="*"> 
  <td><xsl:value-of select="name()"/></td>
  <td><xsl:value-of select="@rdf:resource"/>
      <xsl:value-of select="//*/rdf:Description"/>
  </td>
 </xsl:for-each>

    </tr>
    </xsl:for-each>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

通过XSLT,我能够为Subject,Predicate生成正确的结果,但不能为Object生成正确的结果,因为一些对象是封装在XML元素中的文字。我尝试使用xsl:value-of select =“// * / rdf:Description”/但它只返回文档的所有文字。请帮忙,谢谢。

1 个答案:

答案 0 :(得分:2)

<xsl:value-of select="*/."/><xsl:value-of select="*/text()"/>应该可以解决问题,因为您在描述范围内并且正在寻找描述内容。

两个选择都返回子元素内所有文本的串联。如果在Description元素中有结构,则可能需要调整样式以合并它。

在更多“xsl afine”样式中,即不使用for-each循环但是tempate样式表将如下所示:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
    <xsl:output method="html"/>
    <xsl:template match="/">
        <html>
            <body>

                <table border="1">
                    <tr bgcolor="#5d7b9d" >
                        <th style="color: white">Subject</th>
                        <th style="color: white">Predicate</th>
                        <th style="color: white">Object</th>
                    </tr>

                    <xsl:apply-templates select="rdf:RDF/rdf:Description"/>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="rdf:RDF/rdf:Description">
        <tr>
            <td>
                <xsl:value-of select="@rdf:about"/>
            </td>
            <td>
                <xsl:value-of select="name()"/>
            </td>
            <td>
                <xsl:choose>
                    <xsl:when test="*/@rdf:resource">
                    <xsl:value-of select="*/."/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="*/."/>
                </xsl:otherwise>
            </xsl:choose>
            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet>

在这个样式表中,恕我直言,评估的实际范围变得更加清晰。

如果您想确保只显示资源或内容,并且还要处理多个元素,您可以修改上面的样式表,如下所示:

<xsl:template match="rdf:RDF/rdf:Description">
    <tr>
        <td>
            <xsl:value-of select="@rdf:about"/>
        </td>
        <td>
            <xsl:value-of select="name()"/>
        </td>
        <td>
            <xsl:apply-templates select="rdf:RDF/rdf:Description/*"/>
        </td>
    </tr>
</xsl:template>

<xsl:template match="rdf:RDF/rdf:Description/*">
    <!-- implements either or -->
    <xsl:choose>
        <xsl:when test="*/@rdf:resource">
            <xsl:value-of select="*/."/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="*/."/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>