Как получить правильные значения из второго файла XML? - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь взять два отдельных файла XML и с помощью XSL превратить их в один файл HTML. Я получаю правильные вещи из первого 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-файла, мне нужно первое слово от каждого, затем второе слово и так далее. Я получаю правильные из оригинального XML, но только первое слово «pas» из второго XML-файла.

Ожидаемый результат:

Danish
hund
kaffe 
trä  
stol  
lommelygte 
kat
fisk
bil
telefon 
skov
Croatian
pas 
kava
drvo
stolica
baterija
macka
riba
automobil
telefon
suma

Ответы [ 3 ]

1 голос
/ 25 октября 2019

Я подумал, что вы захотите поместить два списка рядом, как в словаре. Получить показанный результат из двух отдельных списков довольно тривиально:

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>
0 голосов
/ 26 октября 2019

Это расширение комментариев после ответа Parfait.

В своем ответе Парфе говорит:

В вашем случае, поскольку вам необходимо пересечь узлы во внешнем документе, xsl:for-each неизбежно:

В комментарии я спросил, почему это так, и Парфе ответил:

Если вы можете показать, как избежать xsl:for-each на узлах через document(), я очень заинтересован!

В следующей таблице стилей показано, как получить тот же результат, используя только 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-templates в этом случае лучше, чем xsl:for-each.

0 голосов
/ 25 октября 2019

В увлекательном обсуждении XSLT Для циклов вместо 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...