很抱歉这个菜鸟问题,我已经通过添加不是很优雅的空模板解决了这个问题,但是谁能帮助我理解为什么我在输出中仍然看到另一个“级别”的值?
这是我的xml的样子:
<root>
<offers>
<theme>
<type>theme1</type>
<name>...</name>
<slug>...</slug>
<description>...</description>
<total>32</total>
<url_title>...</url_title>
<url_anchor>...</url_anchor>
<url>...</url>
<offers>
<row>
<offer>
<name>travel</type>
<id>68232</id>
</theme>
<theme>
<type>theme2</type>
<name>...</name>
<slug>...</slug>
<description>...</description>
<total>32</total>
<url_title>...</url_title>
<url_anchor>...</url_anchor>
<url>...</url>
<offers>
<row>
<offer>
<name>clowns</type>
<id>222</id>
</theme>
</offers>
</root>
每个主题仅包含1个报价。我想同时显示主题/要约/行/要约的报价,所以我使用了:
<xsl:template match="root/offers">
<xsl:apply-templates select="theme[position() mod 2 = 1]" mode="row" />
</xsl:template>
<xsl:template match="theme" mode="row">
<xsl:apply-templates select="offers/row/offer/." mode="offer1" />
<xsl:apply-templates select="following-sibling::theme[1]" mode="offer2" />
</xls:template>
<xsl:template match="*" mode="offer1">
=== This one showed the offer correctly
</template>
<xsl:template match="offer" mode="offer2">
=== This one kept showing the 'type', 'name' 'slug'
=== values from the theme node,
=== even though I didn't ask for them
</xsl:template>
我只是通过添加空模板来修复它,就像这样:
<xsl:template match="theme/type" mode="offer2"/>
<xsl:template match="theme/name" mode="offer2"/>
<xsl:template match="theme/slug" mode="offer2"/>
我只想了解我哪里出错了。我一直对同级语法不满意(那里不能使用'.'...),我需要在'theme'级别使用mod 2 = 1,因为每个主题仅包含一个提议。
答案 0 :(得分:1)
出现问题的原因是Built-in Template Rules
让我们看看这个规则:
<xsl:template match="theme" mode="row">
<xsl:apply-templates select="offers/row/offer/." mode="offer1" />
<xsl:apply-templates select="following-sibling::theme[1]" mode="offer2" />
</xls:template>
请注意如何应用选择offer
孙子和主题兄弟的模板。因此,由于在theme
模式下没有针对offer2
元素的规则,因此将应用内置规则:元素将应用子节点,输出文本节点。
这就是为什么转换(不是您说的规则)输出
的原因主题节点中的“类型”,“名称”,“子弹”,值,即使我 没有要他们
更新:来自OP的评论
是的,那么我如何将它们丢失,同时仍将它们配对
推送样式:将规则更改为
<xsl:template match="theme" mode="row">
<xsl:apply-templates
select="offers/row/offer" mode="offer1" />
<xsl:apply-templates
select="following-sibling::theme[1]/offers/row/offer" mode="offer2" />
</xls:template>
拉样式:添加此规则可覆盖'offer2'
模式下的文本节点内置规则。
<xsl:template match="text()" mode="offer2"/>
答案 1 :(得分:0)
您已在此处https://www.w3.org/TR/1999/REC-xslt-19991116将其标记为XSLT 1.0版规范
如果您想使用https://www.w3.org/TR/2009/PER-xslt20-20090421/上的2.0版本
列表可以在https://www.w3.org/TR/xslt/all/
中找到您的答案就在于副本在1.0中的工作方式:https://www.w3.org/TR/1999/REC-xslt-19991116#copying,但也许对这里的2.0规范有更好的解释https://www.w3.org/TR/xslt20/#copying
您拥有的此版本1.0可能会有所不同,这可能会影响答案的有效性。
好的,我们已经解决了这个问题,让我们使用您发布的XML。现在,我添加了另一个报价(现实生活中可能会发生吗?),所以我展示了如何通过id获取所有报价和订单。
在大多数情况下,我会尝试简化选择器,在此说明如何进行选择,看来您想对报价进行排序,所以在此示例中。
<?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"
exclude-result-prefixes="xsl html">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="root/offers">
<!-- made this root up -->
<myoffers>
<!-- since we do not need anything from the theme -->
<xsl:apply-templates select="theme/offers/row/offer">
<!-- or sort by <xsl:sort select="name" data-type="string"/> -->
<xsl:sort select="id" data-type="number"/>
</xsl:apply-templates>
</myoffers>
</xsl:template>
<xsl:template match="row/offer">
<!-- could create new node name here like myoffers -->
<xsl:copy>
<!-- order the elements -->
<xsl:apply-templates select="id" />
<xsl:apply-templates select="name" />
</xsl:copy>
</xsl:template>
<xsl:template match="id | name">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- strip/normalize space, not sure you need but to show how -->
<xsl:template match="text()">
<xsl:value-of select="normalize-space()"/>
</xsl:template>
</xsl:stylesheet>
示例输出:
<myoffers> <offer> <id>222</id> <name>clowns</name> </offer> <offer> <id>723</id> <name>burnt meat</name> </offer> <offer> <id>68232</id> <name>travel</name> </offer> </myoffers>
我使用的示例输入XML:
<root>
<offers>
<theme>
<type>theme1</type>
<name>...</name>
<slug>...</slug>
<description>...</description>
<total>32</total>
<url_title>.uuseful..</url_title>
<url_anchor>fun</url_anchor>
<url>...</url>
<offers>
<row>
<offer>
<name>travel</name>
<id>68232</id>
</offer>
</row>
</offers>
</theme>
<theme>
<type>theme2</type>
<name>.namer..</name>
<slug>.slugger..</slug>
<description>.I am me.</description>
<total>32</total>
<url_title>...</url_title>
<url_anchor>...</url_anchor>
<url>...</url>
<offers>
<row>
<offer>
<name>clowns </name>
<id> 222</id>
</offer>
</row>
</offers>
</theme>
<theme>
<type>theme2</type>
<name>.namer..</name>
<slug>.slugger..</slug>
<description>.I am me.</description>
<total>32</total>
<url_title>...</url_title>
<url_anchor>...</url_anchor>
<url>...</url>
<offers>
<row>
<offer>
<name>burnt meat</name>
<id> 723</id>
</offer>
</row>
</offers>
</theme>
</offers>
</root>
如果将其粘贴到http://fiddle.frameless.io/
,则可以测试所有内容