如何从第二个XML文件中获得正确的值

  • 本文关键字:第二个 XML 文件 xml xslt
  • 更新时间 :
  • 英文 :


我试图将两个单独的XML文件合并为一个HTML文件,并使用XSL。我从第一个XML中得到了正确的东西,但当我从第二个XML中尝试同样的东西时,我要么在一行中得到所有单词,要么只在第一行中得到好几次。

XML1

<?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>

XML2

<?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

我想你应该把这两个列表放在一起,就像在字典里一样。要获得两个单独列表的显示结果是相当琐碎的:

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>

根据引人入胜的XSLT讨论对于循环与应用模板,请考虑一个替代版本以避免多次<xsl:for-each>调用。根据XSLT大师(@Tomalak、@DimitreNovatchev、@MichaelKay(的建议:

  • 使用for-each会使程序变得更复杂添加嵌套级别,重用代码也是不可能的每个块的内部。使用apply-templates将(完成时右(生成更灵活、更模块化的XSLT。

  • 使用<xsl:template><xsl:apply-templates>更强大、更优雅。。。xsl:apply-templatesxsl:for-each丰富和深入得多,即使只是因为我们不知道将在选择的节点上应用什么代码——在一般情况下,节点列表的不同节点的代码也会不同。

  • xsl:apply-templates相对于for-each的主要优势在于,代码能够更好地适应不断变化的文档结构和不断变化的处理要求。


在您的情况下,由于您需要遍历外部文档中的节点,xsl:for-each是不可避免的:

XSLT (使用lexiconlanguageword模板(

<?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>

这是Parfait回答后注释的扩展。

Parfait在回答中说:

在您的情况下,由于您需要遍历外部文档中的节点,xsl:for-each是不可避免的:

在一条评论中,我问为什么会这样,Parfait回答说:

如果你能展示如何通过document()避免节点上的xsl:for-each,我很感兴趣!

下面的样式表显示了如何仅使用apply-templates:获得相同的结果

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>
<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-templatesxsl:for-each更好。

最新更新