我正在尝试转换XML文件,但我被阻止了。我们的想法是将<ore:Aggregation>
节点中的每个元素聚合到下一个节点。这是某种逐项。但是每创建edm:WebResource
我不能超过1 dc:item
。
<rdf:RDF>
<ore:Aggregation rdf:about="id1">
<some:crap/>
</ore:Aggregation>
<edm:ProvidedCHO rdf:about="id1">
<some:crap/>
</edm:ProvidedCHO>
<edm:WebResource rdf:about="some/random/url">
<some:crap/>
</edm:WebResource>
...
(n 'edm:WebResource' nodes)
...
<edm:WebResource rdf:about="some/random/url">
<some:crap/>
</edm:WebResource>
<ore:Aggregation rdf:about="id2">
<some:crap/>
</ore:Aggregation>
<edm:ProvidedCHO rdf:about="id2">
<some:crap/>
</edm:ProvidedCHO>
<edm:WebResource rdf:about="some/random/url">
<some:crap/>
</edm:WebResource>
...
(n 'edm:WebResource' nodes)
...
<edm:WebResource rdf:about="some/random/url">
<some:crap/>
</edm:WebResource>
... and on and on ...
</rdf:RDF>
<xsl:template match="/">
<xsl:apply-templates select="/rdf:RDF/ore:Aggregation"/>
</xsl:template>
<xsl:template match="/rdf:RDF/ore:Aggregation">
<rdf:RDF>
<xsl:for-each select=".">
<dc:item>
<xsl:attribute name="rdf:about">
<xsl:value-of select="concat($fileName, '_item', position())"/>
</xsl:attribute>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::edm:ProvidedCHO[1]"/>
<xsl:copy-of select="following-sibling::edm:WebResource[1]"/>
<!-- WHERE IT SUCKS -->
<xsl:if test="local-name(following-sibling::*[3]) = 'edm:WebResource'">
<xsl:copy-of select="following-sibling::*[3]"/>
</xsl:if>
<!-- ./WHERE IT SUCKS -->
</dc:item>
</xsl:for-each>
</rdf:RDF>
</xsl:template>
另一种带来太多节点的尝试:
<!-- WHERE IT SUCKS -->
<xsl:copy-of select="following-sibling::*[local-name (preceding::*[1]) = 'ore:Aggregation']"/>
<!-- ./WHERE IT SUCKS -->
<!-- ITEM N1 -->
<rdf:RDF>
<dc:item rdf:about="some.concat.string"/>
<ore:Aggregation rdf:about="id1">
<some:crap/>
</ore:Aggregation>
<edm:ProvidedCHO rdf:about="id1">
<some:crap/>
</edm:ProvidedCHO>
<edm:WebResource rdf:about="some/random/url">
<some:crap/>
</edm:WebResource>
</rdf:RDF>
<!-- ITEM N2 -->
<rdf:RDF>
<dc:item rdf:about="some.concat.string"/>
<ore:Aggregation rdf:about="id1">
<etc/>
答案 0 :(得分:2)
在XSLT 2.0中,这似乎是<?php
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query();
$wp_query->query('showposts=24&post_type=movie&orderby=ASC' . '&paged=' . $paged);
while ($wp_query->have_posts()) : $wp_query->the_post();
?>
的工作(参见http://www.xml.com/pub/a/2003/11/05/tr.html)。特别是,将其与xsl:for-each-group
group-starting-with
当定位在父 <xsl:for-each-group select="*" group-starting-with="ore:Aggregation">
元素上时,这将完成,并将所有子元素排列成组,rdf:RDF
是每个组的开头。 ore:Aggregration
中的代码随后会为每个xsl:for-each-group
元素调用一次,然后您可以使用ore:Aggregation
函数访问该组中的所有元素。
尝试使用此XSLT作为初学者
current-group()
请注意,此生成的输出XML格式不正确,因为它缺少单个根元素。如果添加一个会更好,不仅仅是为了使其形成良好,但是命名空间声明也会在一个地方出现:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:rdf="rdf" xmlns:ore="ore" xmlns:dc="dc">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="rdf:RDF">
<xsl:for-each-group select="*" group-starting-with="ore:Aggregation">
<rdf:RDF xmlns:edm="edm" xmlns:ore="ore" xmlns:some="some">
<dc:item rdf:about="{concat('item', position())}" />
<xsl:apply-templates select="current-group()" />
</rdf:RDF>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
另请注意在创建<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:rdf="rdf" xmlns:ore="ore" xmlns:dc="dc">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="rdf:RDF">
<rdf:root xmlns:edm="edm" xmlns:ore="ore" xmlns:some="some">
<xsl:for-each-group select="*" group-starting-with="ore:Aggregation">
<rdf:RDF>
<dc:item rdf:about="{concat('item', position())}" />
<xsl:apply-templates select="current-group()" />
</rdf:RDF>
</xsl:for-each-group>
</rdf:root>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
时使用Attribute Value Templates,这进一步减少了所需的代码量。
答案 1 :(得分:1)
我之前已经遇到过这种情况,而且我能够提出的最佳解决方案涉及设置操作。
在某种程度上这是有道理的,因为你想要在每个矿石之后的所有节点:聚合直到下一个矿石:聚合。
换句话说,您希望所有以下节点除之外的下一个节点:聚合和后面的所有内容。
值得庆幸的是,在XSLT 2.0中我们已经设置了操作运算符,因此我们不必跳过我们在XSLT 1.0中必须要做的复杂箍。
试试这个XPATH
following-sibling::node() except
(following-sibling::ore:Aggregation |
following-sibling::ore:Aggregation/following-sibling::node())
这应该为您提供您期望的节点集。
每次尝试将平面元素列表排序为某种结果结构时,此模式通常起作用。例如,我遇到的问题是找到具有特定属性的所有元素,然后将它们分组为一个。
因此,一般的解决方案是(伪代码)
如果我们可以同时指定终端标签及其兄弟姐妹,这会更简单一点,但这实际上并不太糟糕。
following-sibling::node() except
(following-sibling::{next-node-selection-criteria} |
following-sibling::{next-node-selection-criteria}/following-sibling::node())