这是我的XML代码的相关部分:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE recipeml SYSTEM "recipeml.dtd">
<recipeml>
<recipe>
<head>
<title>Coq au Riesling</title>
</head>
<ingredients>
<ing>
<amt>
<qty>30</qty>
<unit system="metric">ml</unit>
</amt>
<item>garlic-infused olive oil</item>
</ing>
<ing>
<amt>
<qty>150</qty>
<unit system="metric" unit="g">gram(s)</unit>
</amt>
<item>bacon lardons</item>
</ing>
<ing>
<amt>
<qty>1</qty>
</amt>
<item>leek(s)</item>
<prep>(finely sliced)</prep>
</ing>
<ing>
<amt>
<qty>12</qty>
</amt>
<item>chicken thighs (boneless and skinned)</item>
</ing>
<ing>
<amt>
<qty>3</qty>
</amt>
<item>bay leaves</item>
</ing>
<ing>
<amt>
<qty>300</qty>
<unit system="metric">gram(s)</unit>
</amt>
<item>oyster mushroom(s) (torn into strips)</item>
</ing>
<ing>
<amt>
<qty>750</qty>
<unit system="metric">ml</unit>
</amt>
<item>Riesling</item>
</ing>
<ing>
<amt>
<qty> 1</qty>
<unit>splash of</unit>
</amt>
<item>double cream (optional)</item>
</ing>
<ing>
<amt>
<qty> 1</qty>
<unit>pinch of</unit>
</amt>
<item>salt</item>
</ing>
<ing>
<amt>
<qty>1</qty>
<unit>pinch of </unit>
</amt>
<item>Pepper</item>
</ing>
<ing>
<amt>
<qty>1</qty>
<unit>tablespoon(s)</unit>
</amt>
<item>dill (chopped to serve (2 tablespoons if needed)) </item>
</ing>
</ingredients>
这是我的XSLT:
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates>
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="recipeml/recipe/head/title">
<h3>
<xsl:value-of select="."/>
</h3>
</xsl:template>
<xsl:template match="recipeml/recipe/ingredients">
<ul>
<xsl:for-each select="ing">
<li><xsl:value-of select="item"/>
<ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="recipeml/recipe/directions">
<xsl:for-each select="*[not(preceding-sibling::step)]"/>
<xsl:for-each select="*[not(following-sibling::note)]"/>
</xsl:template>
我的问题是在这里。我希望它仅在没有单位元素的情况下显示数量。我测试了我的xpath并成功了,但是当我应用我的场景时,它假定每个项目的数量为1。
<ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>
这是我得到的输出:
<html>
<body>
<h3>Coq au Riesling</h3>
<ul>
<li>garlic-infused olive oil
<ul>1</ul>
</li>
<li>bacon lardons
<ul>1</ul>
</li>
<li>leek(s)
<ul>1</ul>
</li>
<li>chicken thighs (boneless and skinned)
<ul>1</ul>
</li>
<li>bay leaves
<ul>1</ul>
</li>
<li>oyster mushroom(s) (torn into strips)
<ul>1</ul>
</li>
<li>Riesling
<ul>1</ul>
</li>
<li>double cream (optional)
<ul>1</ul>
</li>
<li>salt
<ul>1</ul>
</li>
<li>Pepper
<ul>1</ul>
</li>
<li>dill (chopped to serve (2 tablespoons if needed))
<ul>1</ul>
</li>
</ul>
我需要更改使其仅显示韭菜,鸡大腿和月桂叶的amt吗?
答案 0 :(得分:0)
以“ /”或“ //”开头的路径表达式总是从树的根中选择。你写
<xsl:for-each select="ing">
<li><xsl:value-of select="item"/>
<ul><xsl:value-of select="//amt/child::qty[not(following-sibling::unit)]"/></ul></li>
</xsl:for-each>
但是amt
是ing
的子代,因此您只想要select="amt/qty[...]"
。您也可以写select="amt[not(unit)]/qty"
。
(顺便提一下,您的问题为我们提供了答案的线索。在一个上下文中正确的XPath表达式在另一个上下文中可能是完全错误的。了解XSLT如何更改上下文节点以评估XPath表达式至关重要。)>
顺便说一句您的最后一个模板规则:
<xsl:template match="recipeml/recipe/directions">
<xsl:for-each select="*[not(preceding-sibling::step)]"/>
<xsl:for-each select="*[not(following-sibling::note)]"/>
</xsl:template>
将永远不会产生任何输出。这两个xsl:for-each
指令为空,因此您说的是“对于每个xxxx,什么也不做”-始终不执行任何操作。
答案 1 :(得分:0)
考虑使用模板进行调整,以使模板沿树(食谱级别,成分级别, ing 级别)走下端对 ing 节点应用了两个集合。
使用这种方法,可以避免从根recipeml
匹配多个模板,使用xsl:foreach
,使用following-sibling
以及使用//
进行绝对引用。并确保添加<xsl:strip-space>
来从源XML中删除空格和换行符。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="recipeml/recipe">
<html>
<body>
<h3>
<xsl:value-of select="head/title"/>
</h3>
<xsl:apply-templates select="ingredients"/>
</body>
</html>
</xsl:template>
<xsl:template match="ingredients">
<xsl:apply-templates select="ing[not(amt/unit)]"/>
<xsl:apply-templates select="ing[amt/unit]"/>
</xsl:template>
<xsl:template match="ing[not(amt/unit)]">
<ul>
<li><xsl:value-of select="item"/>
<ul>
<xsl:value-of select="amt/qty"/>
</ul>
</li>
</ul>
</xsl:template>
<xsl:template match="ing[amt/unit]">
<ul>
<li><xsl:value-of select="item"/>
</li>
</ul>
</xsl:template>
</xsl:stylesheet>