我正在尝试获取两个单独的XML文件,并使用XSL将它们合并为一个HTML文件。我从第一个XML得到了正确的东西,但是当我从第二个XML尝试得到相同的东西时,我要么将所有单词排成一行,要么仅将第一个单词得到几次。
XML 1
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="xsltcss.css"?>
<?xml-stylesheet type="text/xsl" href="xslt.xsl" ?>
<lexicon>
<head>
<title>Danish</title>
<author>Mattias Liljegren</author>
</head>
<language value="danish">
<word value="dog">hund</word>
<word value="coffee">kaffe</word>
<word value="tree">træ</word>
<word value="chair">stol</word>
<word value="flashlight">lommelygte</word>
<word value="cat">kat</word>
<word value="fish">fisk</word>
<word value="car">bil</word>
<word value="phone">telefon</word>
<word value="forest">skov</word>
</language>
</lexicon>
XML 2
<?xml version="1.0" encoding="UTF-8"?>
<lexicon>
<head>
<title>Croatian</title>
<author>Mattias Liljegren</author>
</head>
<language value="croatian">
<word value="dog">pas</word>
<word value="coffee">kava</word>
<word value="tree">drvo</word>
<word value="chair">stolica</word>
<word value="flashlight">baterija</word>
<word value="cat">mačka</word>
<word value="fish">riba</word>
<word value="car">automobil</word>
<word value="phone">telefon</word>
<word value="forest">šuma</word>
</language>
</lexicon>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" type="text/css" href="xsltcss.css" />
</head>
<body>
<xsl:for-each select="lexicon/head/title">
<p>
<xsl:value-of select="." />
</p>
<p>
<xsl:value-of select="document('kroatiska.xml')/lexicon/head/title/." />
</p>
</xsl:for-each>
<xsl:for-each select="lexicon/language/word">
<p>
<xsl:value-of select="." />
</p>
</xsl:for-each>
<xsl:for-each select="lexicon/language/word">
<p>
<xsl:value-of select="document('kroatiska.xml')/lexicon/language/word" />
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
两个单独的xml文件,我想要每个文件的第一个单词,然后是第二个单词,依此类推。 Atm我从原始xml中得到了正确的答案,但是从第二个xml文件中仅得到了第一个单词“ pas”。
预期结果:
Danish
hund
kaffe
trä
stol
lommelygte
kat
fisk
bil
telefon
skov
Croatian
pas
kava
drvo
stolica
baterija
macka
riba
automobil
telefon
suma
答案 0 :(得分:1)
我认为您希望将两个列表并排放置,就像在字典中一样。要获得两个单独列表的显示结果相当简单:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/lexicon">
<html>
<body>
<!-- this document -->
<h3>
<xsl:value-of select="language/@value"/>
</h3>
<xsl:for-each select="language/word">
<p>
<xsl:value-of select="."/>
</p>
</xsl:for-each>
<!-- external document -->
<xsl:variable name="kroatiska" select="document('kroatiska.xml')/lexicon" />
<h3>
<xsl:value-of select="$kroatiska/language/@value"/>
</h3>
<xsl:for-each select="$kroatiska//language/word">
<p>
<xsl:value-of select="."/>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
对于每一个引人入胜的XSLT讨论For loops vs. apply-templates,请考虑使用另一种版本来避免许多<xsl:for-each>
的调用。根据XSLT专家(@Tomalak,@DimitreNovatchev,@MichaelKay)的建议:
使用
for-each
使您的程序更加复杂 添加嵌套级别,也没有可能重复使用代码 在for-each块中。使用apply-templates
将(完成后 右)生成更灵活和模块化的XSLT。
使用
<xsl:template>
和<xsl:apply-templates>
更加强大和优雅……xsl:apply-templates
比xsl:for-each
更加丰富和深入,即使是因为我们不知道什么代码将应用于选择的节点上-通常,此代码对于节点列表的不同节点将有所不同。
与
xsl:apply-templates
相比,for-each
的主要好处是代码可以更好地适应不断变化的文档结构和不断变化的处理要求。
由于您需要遍历外部文档xsl:for-each
中的节点,因此不可避免:
XSLT (使用lexicon
,language
和word
模板)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/lexicon">
<html>
<head>
<link rel="stylesheet" type="text/css" href="xsltcss.css" />
</head>
<xsl:apply-templates select="language" />
</html>
</xsl:template>
<xsl:template match="language">
<body>
<xsl:variable name="other_doc" select="document('kroatiska.xml')" />
<h3>
<xsl:value-of select="@value"/>
</h3>
<xsl:apply-templates select="word" />
<h3>
<xsl:value-of select="$other_doc/lexicon/language/@value" />
</h3>
<xsl:for-each select="$other_doc/lexicon/language/word">
<p>
<xsl:value-of select="text()" />
</p>
</xsl:for-each>
</body>
</xsl:template>
<xsl:template match="word">
<p>
<xsl:value-of select="text()" />
</p>
</xsl:template>
</xsl:stylesheet>
HTML
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="xsltcss.css">
</head>
<body>
<h3>danish</h3>
<p>hund</p>
<p>kaffe</p>
<p>træ</p>
<p>stol</p>
<p>lommelygte</p>
<p>kat</p>
<p>fisk</p>
<p>bil</p>
<p>telefon</p>
<p>skov</p>
<h3>croatian</h3>
<p>pas</p>
<p>kava</p>
<p>drvo</p>
<p>stolica</p>
<p>baterija</p>
<p>mačka</p>
<p>riba</p>
<p>automobil</p>
<p>telefon</p>
<p>šuma</p>
</body>
</html>
答案 2 :(得分:0)
这是Parfait回答后评论的扩展。
Parfait在回答中说:
由于您需要遍历外部文档
SELECT
中的节点,因此不可避免:
在评论中,我问为什么会这样,冻糕回答:
如果您可以展示如何通过
xsl:for-each
避免在节点上使用xsl:for-each
,我非常感兴趣!
以下样式表显示了如何仅使用document()
来获得相同的结果:
XSLT 1.0
apply-templates
这并不意味着在这种情况下使用<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/lexicon">
<html>
<body>
<xsl:apply-templates select="language | document('kroatiska.xml')/lexicon/language" />
</body>
</html>
</xsl:template>
<xsl:template match="language">
<h3>
<xsl:value-of select="@value"/>
</h3>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="word">
<p>
<xsl:value-of select="."/>
</p>
</xsl:template>
</xsl:stylesheet>
比xsl:apply-templates
更好。