我是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
答案 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>
答案 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");
}