使用XSLT将XML文件转换为RDF / XML

时间:2014-09-21 12:21:34

标签: xml xslt rdf

我是XSLT的新手。我有一个XML文件,并希望使用XSLT将其转换为RDF / XML。实际上我找到了一个XSLT的样式表,并且在它和XML文件之间建立链接,结果只显示在"文字"在浏览器而不是XML文件。我的问题是:我希望以RDF / XML格式获得转换结果,但不幸的是我得到的结果是纯文本。

XMl文件

    <xml>
<?xml-stylesheet type="text/xsl" href="qu.xsl"?>
    <person>
    <name>Joe</name>
    <website url="www.example1.com">contact1</website >
    <vote>20</vote>
    </person>
    <person>
     <name>Anna</name>
    <website url="www.example2.com">contact2</website>
     <vote>80</vote>
     </person>
     </xml>

和XSLT样式表是

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:html="http://www.w3.org/1999/xhtml"
            xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
            xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
            xmlns:foaf="http://xmlns.com/foaf/spec/"
            xmlns:foo="http://example.com/foo#">

<xsl:template match="/">
    <rdf:RDF>
        <rdf:Description rdf:about="http://www.example.com/xml">
            <xsl:apply-templates/>
    </rdf:Description>
    </rdf:RDF>
</xsl:template>

<xsl:template match="person">
<xsl:variable name="critic"><xsl:value-of select="name"/></xsl:variable>
<xsl:variable name="criticWebsite"><xsl:value-of select="website/@url"/</xsl:variable>
<foo:hasCritic>
    <rdf:Description rdf:about="http://www.example.com/critic/{$critic}">
        <foaf:name><xsl:value-of select="name"/></foaf:name>
        <foaf:homepage>
            <rdf:Description rdf:about="http://{$criticWebsite}">
                <rdfs:label><xsl:value-of select="website"/></rdfs:label>
            </rdf:Description>
        </foaf:homepage>
    </rdf:Description>
</foo:hasCritic>
</xsl:template>

</xsl:stylesheet>

但结果是: Joe contact1 20 Anna contact2 80

2 个答案:

答案 0 :(得分:2)

您的XSLT(错误地固定在criticWebsite xsl:value-of附近):

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
                xmlns:foaf="http://xmlns.com/foaf/spec/"
                xmlns:foo="http://example.com/foo#">

  <xsl:template match="/">
    <rdf:RDF>
      <rdf:Description rdf:about="http://www.example.com/xml">
        <xsl:apply-templates/>
      </rdf:Description>
    </rdf:RDF>
  </xsl:template>

  <xsl:template match="person">
    <xsl:variable name="critic"><xsl:value-of select="name"/></xsl:variable>
    <xsl:variable name="criticWebsite"><xsl:value-of select="website/@url"/></xsl:variable>
    <foo:hasCritic>
      <rdf:Description rdf:about="http://www.example.com/critic/{$critic}">
        <foaf:name><xsl:value-of select="name"/></foaf:name>
        <foaf:homepage>
          <rdf:Description rdf:about="http://{$criticWebsite}">
            <rdfs:label><xsl:value-of select="website"/></rdfs:label>
          </rdf:Description>
        </foaf:homepage>
      </rdf:Description>
    </foo:hasCritic>
  </xsl:template>

</xsl:stylesheet>

应用于您的输入XML文件(xml-stylesheet声明在XML声明的正下方移动,并且XSLT文件的路径是绝对的):

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="file:///c:/path/to/XSLT/qu.xsl"?>
<xml>
  <person>
    <name>Joe</name>
    <website url="www.example1.com">contact1</website >
    <vote>20</vote>
  </person>
  <person>
    <name>Anna</name>
    <website url="www.example2.com">contact2</website>
    <vote>80</vote>
  </person>
</xml>

生成此RDF文档:

<?xml version="1.0" encoding="UTF-8"?><rdf:RDF xmlns:html="http://www.w3.org/1999/xhtml" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/spec/" xmlns:foo="http://example.com/foo#"><rdf:Description rdf:about="http://www.example.com/xml">
  <foo:hasCritic><rdf:Description rdf:about="http://www.example.com/critic/Joe"><foaf:name>Joe</foaf:name><foaf:homepage><rdf:Description rdf:about="http://www.example1.com"><rdfs:label>contact1</rdfs:label></rdf:Description></foaf:homepage></rdf:Description></foo:hasCritic>
  <foo:hasCritic><rdf:Description rdf:about="http://www.example.com/critic/Anna"><foaf:name>Anna</foaf:name><foaf:homepage><rdf:Description rdf:about="http://www.example2.com"><rdfs:label>contact2</rdfs:label></rdf:Description></foaf:homepage></rdf:Description></foo:hasCritic>
</rdf:Description></rdf:RDF>

说明:

  • 要在Firefox中查看此内容,请右键单击输出并选择&#34; Inspect 元素&#34;,否则你只会看到&#34; Joecontact1 Annacontact2&#34;。
  • 这不适用于Chrome中的本地文件,因为Chrome refuses to run locally loaded XSLT。它必须从服务器远程加载才能工作。

答案 1 :(得分:0)

将XML转换为RDF也可以使用XmlToRdf库在Java中完成。

我在github上提出了一个有效的例子:https://github.com/hmottestad/XmlToRdf---Example-from-Stack-Overflow-1

以下是转换为RDF Turtle的结果

<http://www.example1.com>
    rdfs:label  "contact1" .

<http://www.example2.com>
    rdfs:label  "contact2" .

<http://www.example.com/critic/Anna>
    a              foaf:Person ;
    foaf:homepage  <http://www.example2.com> ;
    foaf:name      "Anna" ;
    foaf:vote      "80" .

<http://www.example.com/critic/Joe>
    a              foaf:Person ;
    foaf:homepage  <http://www.example1.com> ;
    foaf:name      "Joe" ;
    foaf:vote      "20" .

[ a              <http://example.com/xml> ;
  foo:hasCritic  <http://www.example.com/critic/Anna> ,     <http://www.example.com/critic/Joe>
] .

使用以下java代码

public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {

    XmlToRdfAdvancedJena build = Builder.getAdvancedBuilderJena()

        // set base namesapce to the foaf namespace
        .setBaseNamespace(FOAF.NS, Builder.AppliesTo.bothElementsAndAttributes)

        // <foaf:person> should be renamed to <foaf:Person> (setBaseNamespace is applied first :)
        .renameElement(FOAF.Person.toString().toLowerCase(), FOAF.Person.toString())

        // used foaf:homepage instead of website
        .renameElement(FOAF.NS + "website", FOAF.homepage.toString())

        // build an IRI for our <foaf:Person> tags (rename is applied first :)
        // IRI should be "http://www.example.com/critic/" + the contents of <foaf:name>
        .compositeId(FOAF.Person.toString()).fromElement(FOAF.name.toString()).mappedTo((elments, attributes) -> "http://www.example.com/critic/" + elments.get(FOAF.name.toString()))

        // not everything should use the foaf namespace, so rename our root xml tag to http://example.com/xml
        .renameElement(FOAF.NS + "xml", "http://example.com/xml")

        // insert foo:hasCritic instead of the default xmlToRdf:hasChild predicate between the root <xml> tag and the <foaf:Person>
        .insertPredicate("http://example.com/foo#hasCritic").betweenAnyParentAndSpecificChild(FOAF.Person.toString())
        .build();

    Model model = build
        .convertForPostProcessing(new FileInputStream("input.xml"))

        // we need to do a bit of post processing using SPARQL
        // this sparql adds foaf:homepage to person based on the "url" attribute in the <website> elements
        // it also uses the inner text of the <website> tag as the rdfs:label og the homepage
        .mustacheTransform(new ByteArrayInputStream(String.join("\n",
            "insert{",
            "   ?person <{{{foafHomepage}}}> ?urlResource.",
            "  ?urlResource <{{rdfsLabel}}> ?contact.",
            "}",
            "where{",
            "   ?a a <{{{foafHomepage}}}>;",
            "       <http://xmlns.com/foaf/0.1/url> ?url ; ",
            "       <{{{hasValue}}}> ?contact . ",

            "   ?person ?prop ?a.",
            "    BIND( IRI(CONCAT(\"http://\",?url)) as ?urlResource).",
            "}"

        ).getBytes("utf-8")), new Object() {
            String foafHomepage = FOAF.homepage.toString();
            String rdfsLabel = RDFS.label.toString();

            String hasValue = "http://acandonorway.github.com/XmlToRdf/ontology.ttl#hasValue";
        })


        // finally we can do a bit of cleanup and remove everything related to the <website> tag
        .mustacheTransform(new ByteArrayInputStream(String.join("\n",
            "delete{",
            "   ?a <{{{hasChild}}}> ?child.",
            "   ?child ?b ?c.",
            "}",
            "where{",
            "   ?a <{{{hasChild}}}> ?child.",
            "   ?child ?b ?c.",
            "}"

        ).getBytes("utf-8")), new Object() {

            String hasChild = "http://acandonorway.github.com/XmlToRdf/ontology.ttl#hasChild";

        })


        .getModel();

    // set our namespaces to make everything pretty
    model.setNsPrefix("foaf", FOAF.NS);
    model.setNsPrefix("rdfs", RDFS.getURI());
    model.setNsPrefix("foo", "http://example.com/foo#");

    // output our result to output.ttl
    model.write(new FileOutputStream("output.ttl"), "TTL");


}