Объединить два XML, а затем преобразовать объединенный XML - PullRequest
0 голосов
/ 19 декабря 2009

Я работаю над XSLT-преобразованием, которое состоит в объединении двух XML и последующем преобразовании результата с использованием другого шаблона. Идея состоит в том, что в зависимости от поля исходного XML-файла, вторичный XML-файл изменяется. Например:

<?xml version="1.0" encoding="UTF-8"?>
<data>
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
</data>

в зависимости от значения языкового узла (назовем его LANG), должен быть добавлен файл с названием language {LANG} .xml. Содержимое этих файлов выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<labels>
 <l1001>cliente</l1001>
 <l1002>moneda de referencia</l1002>
</labels>

примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<document>
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
 <labels>
  <l1001>cliente</l1001>
  <l1002>moneda de referencia</l1002>
 </labels>
</document>

И результат этого должен быть преобразован. Я создал следующий шаблон для слияния:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:java="http://xml.apache.org/xalan/java/java.lang" xmlns:xfc="http://www.metafocus.no/digiforms/component">
 <xsl:template match="data">
  <document>
   <xsl:call-template name="copy"/>
   <xsl:variable name="label_file_name" select="concat('Labels_',information/stmtinfo/language,'.xml')"/>
   <xsl:variable name="labels">
    <xsl:copy-of select="document($label_file_name)"/>
   </xsl:variable>
   <xsl:for-each select="xalan:nodeset($labels)/node()">
    <xsl:call-template name="copy"/>
   </xsl:for-each>
  </document>
 </xsl:template>
 <xsl:template name="copy">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Если я пользуюсь этим шаблоном, я получаю следующее:

<?xml version="1.0" encoding="UTF-8"?><document xmlns:xfc="http://www.metafocus.no/digiforms/component" xmlns:java="http://xml.apache.org/xalan/java/java.lang" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xalan="http://xml.apache.org/xalan"><data>
 <information>
  <stmtinfo>
   <type>80</type>
   <language>2</language>
   <clientnum>15907</clientnum>
   <clientname>bogus</clientname>
   <clientaddress>1401 Barnacle Street, Miami, Fl</clientaddress>
  </stmtinfo>
 </information>
</data><labels>
 <l1001>cliente</l1001>
 <l1002>moneda de referencia</l1002>
</labels></document>

Что кажется правильным. Но если я вызову из другого шаблона, обработать полученный XML

<xsl:template match="/">
 <xsl:variable name="link1">
  <xsl:apply-templates mode="link1" select="node()"/>
 </xsl:variable>
 <xsl:value-of select="xalan:nodeset($link1)"/>
</xsl:template>

Я получаю следующее

80 2 15907 фиктивный Улица Барнакл 1401, Майами, Флорида

Так что кажется, что слияние не работает правильно, так как, если я преобразую результат в набор узлов, "метки" узла исчезнут. Что я делаю не так?

Большое спасибо.

Хосе

Ответы [ 2 ]

1 голос
/ 19 декабря 2009

Почему вы делаете двухпроходное преобразование? Мне кажется, что если вы просто положите:

<xsl:variable name="labels" select="document(concat(
   'Labels_', 
   /data/information/stmtinfo/language, 
   '.xml'))"/>

вверху документа, тогда вы можете явно указать $labels в своих шаблонах. Результат первого прохода вашего преобразования не настолько отличается по структуре от исходного XML, что вы действительно получаете все, кроме сложности, выполняя это за два прохода.

Тем не менее, проблема в написанном преобразовании почти наверняка заключается в том, что вы делаете это:

<xsl:value-of select="xalan:nodeset($link1)"/>

вместо этого:

<xsl:copy-of select="xalan:nodeset($link1)"/>

Значением элемента является объединение всех его потомков текстовых узлов, и это то, что вы получаете в своих выходных данных.

0 голосов
/ 19 декабря 2009

Я упростил преобразование, выполнив следующее:

<xsl:template match="data">
    <xsl:variable name="labels" select="document(concat('Labels_',/data/information/stmtinfo/language,'.xml'))"/>
        <xsl:call-template name="letter-layout"/>
        type=<xsl:value-of select="/data/information/stmtinfo/type"/>
        label=<xsl:copy-of select="$labels/l1001"/>
</xsl:template>

но я не заполняю этикетку.

<?xml version="1.0" encoding="UTF-8"?>
            type=80
            label=

Если я не использую / l1101, я получаю следующее:

<?xml version="1.0" encoding="UTF-8"?>
            type=80
            label=<labels>
    <l1001>cliente</l1001>
    <l1002>moneda de referencia</l1002>
</labels>

Так что у меня сложилось впечатление, что импортированный xml обрабатывается как текст, а не как набор узлов

...