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

时间:2019-10-25 09:54:22

标签: xml xslt

我正在尝试获取两个单独的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

3 个答案:

答案 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-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>

答案 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更好。