Xml 如何使用XSL将几个新元素插入到另一个元素中,保持其他所有内容不变
我编写了一个XSLT,它应该在父rdf:Description元素中添加一个或多个skos:slowner元素。下面是一段起始xml:Xml 如何使用XSL将几个新元素插入到另一个元素中,保持其他所有内容不变,xml,xslt,rdf,Xml,Xslt,Rdf,我编写了一个XSLT,它应该在父rdf:Description元素中添加一个或多个skos:slowner元素。下面是一段起始xml: <rdf:Description rdf:about="http://schema.xxx.com/ns/vocabulary-structure/AAA"> <rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/> <
<rdf:Description rdf:about="http://schema.xxx.com/ns/vocabulary-structure/AAA">
<rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>
<skos:prefLabel xml:lang="en">AAA</skos:prefLabel>
<skos:broader rdf:resource="http://schema.xxx.com/ns/vocabulary-structure/AA"/>
</rdf:Description>
我想为xml中每个较窄的元素添加一个元素:
<rdf:Description rdf:about="http://schema.xxx.com/ns/vocabulary-structure/AAA">
<skos:narrower rdf:resource="http://schema.xxx.com/ns/vocabulary-structure/AAAA"/>
<rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>
<skos:prefLabel xml:lang="en">AAA</skos:prefLabel>
<skos:broader rdf:resource="http://schema.xxx.com/ns/vocabulary-structure/AA"/>
</rdf:Description>
我需要这样做,以便同时指定skos:broader和skos:broader关系。我使用的词汇表工具只存储skos:broader
我编写的xsl就是这样做的。然而,虽然结果接近我想要的,但它有一个缺陷。如果元素AAA除了AAAA之外还有一个更窄的元素AAAB,那么对于这种情况,我会得到一个单独的rdf:Description元素:
<rdf:Description rdf:about="http://schema.xxx.com/ns/vocabulary-structure/AAA">
<skos:narrower rdf:resource="http://schema.xxx.com/ns/vocabulary-structure/AAAB"/>
<rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>
<skos:prefLabel xml:lang="en">AAA</skos:prefLabel>
<skos:broader rdf:resource="http://schema.xxx.com/ns/vocabulary-structure/AA"/>
</rdf:Description>
我想要的是让两个SKO:更窄的指向AAAA的SKO和指向AAAB的SKO位于同一个AAA元素中,而不是两个单独的元素
下面是xslt的相关部分。有人能指出我做错了什么吗
<xsl:template match="rdf:RDF/rdf:Description" mode="apply-skos-narrower">
<xsl:param name="this-concept-id"/>
<xsl:param name="narrower-concept-id"/>
<xsl:choose>
<xsl:when test="@rdf:about=$this-concept-id">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
<skos:narrower>
<xsl:attribute name="rdf:resource">
<xsl:value-of select="$narrower-concept-id"/>
</xsl:attribute>
</skos:narrower>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:when>
</xsl:choose>
</xsl:template>
谢谢你的评论。下面是所要求的完整xslt。我肯定我在这里误解了递归是如何工作的,所以任何指导都将不胜感激
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="1.0"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- Store the vocabulary identifier as a variable -->
<xsl:variable name="vocabulary-id" select = "//rdf:Description[child::rdf:type[@rdf:resource='http://www.w3.org/2002/07/owl#Ontology']]/@rdf:about" />
<!-- Replace the massive collection of namespace declarations provided by EVN with a more sensible minimal set, then call the first processing template. -->
<xsl:template match="/">
<rdf:RDF xmlns:opencyc="http://sw.opencyc.org/concept/"
xmlns:freebase="http://rdf.freebase.com/ns/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
xmlns:dbpedia="http://dbpedia.org/resource/"
xmlns:sesame="http://www.openrdf.org/schema/sesame#"
xmlns:cycAnnot="http://sw.cyc.com/CycAnnotations_v1#"
xmlns:ctag="http://commontag.org/ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:cyc="http://sw.cyc.com/concept/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<!-- Copy the header and Concept Scheme sections - these are fine -->
<xsl:apply-templates select="/rdf:RDF/rdf:Description" mode="process-vocabulary-header"/>
<xsl:apply-templates select="/rdf:RDF/rdf:Description" mode="process-concept-scheme"/>
<!-- Now process all of the other concepts -->
<xsl:apply-templates select="/rdf:RDF/rdf:Description" mode="process-other-concepts"/>
</rdf:RDF>
</xsl:template>
<!-- Process the vocabulary header information -->
<xsl:template match="rdf:RDF/rdf:Description" mode="process-vocabulary-header">
<xsl:if test="rdf:type[@rdf:resource='http://www.w3.org/2002/07/owl#Ontology']">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<!-- Process the ConceptScheme element -->
<xsl:template match="rdf:Description" mode="process-concept-scheme">
<xsl:if test="rdf:type[@rdf:resource='http://www.w3.org/2004/02/skos/core#ConceptScheme']">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="rdf:RDF/rdf:Description" mode="process-other-concepts">
<xsl:choose>
<!-- When we are in the ConceptScheme element, we can get the concepts that have hasTopConcept elements and set the complementary topConceptOf elements -->
<xsl:when test="rdf:type[@rdf:resource='http://www.w3.org/2004/02/skos/core#ConceptScheme']">
<xsl:for-each select="skos:hasTopConcept">
<xsl:apply-templates select="/rdf:RDF/rdf:Description" mode="apply-top-concepts">
<xsl:with-param name="top-concept-id" select="@rdf:resource"/>
</xsl:apply-templates>
</xsl:for-each>
<!-- Finally, find the elements with skos:broader elements and set their complementary skos:narrower elements -->
</xsl:when>
<xsl:when test="skos:broader">
<xsl:apply-templates select="/rdf:RDF/rdf:Description" mode="apply-skos-narrower">
<xsl:with-param name="this-concept-id" select="skos:broader/@rdf:resource"/>
<xsl:with-param name="narrower-concept-id" select="./@rdf:about"></xsl:with-param>
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- Add the topConceptOf element to the right concepts -->
<xsl:template match="rdf:RDF/rdf:Description" mode="apply-top-concepts">
<xsl:param name="top-concept-id"/>
<xsl:choose>
<xsl:when test="@rdf:about=$top-concept-id">
<xsl:copy>
<xsl:copy-of select="@*"/>
<skos:topConceptOf>
<xsl:attribute name="rdf:resource">
<xsl:value-of select="$vocabulary-id"/>
</xsl:attribute>
</skos:topConceptOf>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:when>
</xsl:choose>
</xsl:template>
<!-- Add the skos:narrower element to the right concepts -->
<xsl:template match="rdf:RDF/rdf:Description" mode="apply-skos-narrower">
<xsl:param name="this-concept-id"/>
<xsl:param name="narrower-concept-id"/>
<xsl:choose>
<xsl:when test="@rdf:about=$this-concept-id">
<xsl:copy>
<xsl:copy-of select="@*|node()"/>
<skos:narrower>
<xsl:attribute name="rdf:resource">
<xsl:value-of select="$narrower-concept-id"/>
</xsl:attribute>
</skos:narrower>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
首先是一个警告:除非真的没有其他选择,否则不应该使用XSLT之类的普通XML处理工具来处理RDF-XML。同一个底层RDF图有许多等价的XML表示,最好使用理解图结构的适当RDF工具 也就是说。。。我认为,使用一个键可以通过它们的rdf:resource来查找skos:wirelater元素,从而以一种非常简单的方式实现您想要的。然后,在处理rdf:Description X时,查找以X为对象的较宽的三元组并创建相应的较窄的反转非常简单
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="1.0"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="broaderByObject" match="skos:broader" use="@rdf:resource" />
<!-- identity template - copy everything as-is except for overrides -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="rdf:Description">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:for-each select="key('broaderByObject', @rdf:about)">
<!-- the object of the narrower is the subject from the broader -->
<skos:narrower rdf:resource="{../@rdf:about}" />
</xsl:for-each>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
同样的原则也适用于顶级概念-添加一个键
<xsl:key name="topConByObject" match="skos:hasTopConcept" use="@rdf:resource" />
然后查找键来创建反转
<xsl:if test="key('topConByObject', @rdf:about)">
<skos:topConceptOf rdf:resource="{$vocabulary-id}" />
</xsl:if>
如果您创建了两个rdf:Description元素,而不是一个,这表明您的模板被调用了两次,或者另一个模板也被复制到了元素中,因此您可能需要包含更多的XSLT,以显示调用模板的方式和位置。谢谢你有和,所以子元素将在添加的更窄元素之前和之后被复制。我觉得你使这比它需要的要困难得多-我将问题归结为为为每个X-更宽-Y添加一个逆三Y-更窄-X,对吗?这非常有效,谢谢。我曾想过用钥匙,但我不知道它是怎么工作的。你很好地澄清了这一点。