XSLT 1.0 - таблица поиска внешних файлов - PullRequest
0 голосов
/ 02 мая 2018

Я использую Perl и модуль CPAN XML :: LibXSLT для выполнения преобразований XML (таким образом, ограничено версией XSLT 1.0). Я совершенно новичок в XSLT-преобразованиях, но нахожу это интересным и потенциально очень мощным. Я хочу преобразовать число в другое, используя внешний файл для поиска, но пока не могу получить желаемые результаты:

D:\>perl
use warnings;
use strict;
use XML::LibXSLT;
use XML::LibXML;
my $xslt = XML::LibXSLT->new();
my $source = XML::LibXML->load_xml(location => 'invoice.xml');
my $style_doc = XML::LibXML->load_xml(location=>'akv2abz.xsl', no_cdata=>1);
my $stylesheet = $xslt->parse_stylesheet($style_doc);
my $results = $stylesheet->transform($source);
print $stylesheet->output_as_bytes($results);
__END__
compilation error: file akv2abz.xsl element stylesheet
xsl:version: only 1.0 features are supported
<?xml version="1.0"?>
<Invoice>
  <AdditionalDocumentReference>
    <DocumentType>ABZ</DocumentType>
    <ID/>
  </AdditionalDocumentReference>
</Invoice>

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

<?xml version="1.0"?>
<Invoice>
  <AdditionalDocumentReference>
    <DocumentType>ABZ</DocumentType>
    <ID>ABC123</ID>
  </AdditionalDocumentReference>
</Invoice>

Файл поиска:

D:\>type lookup.xml
<?xml version="1.0" encoding="utf-8"?>
<QueryResult>
  <Result>
    <ac_name>80186780</ac_name>
    <obj_license>ABC123</obj_license>
  </Result>
  <Result>
    <ac_name>60521933</ac_name>
    <obj_license>DEF567</obj_license>
  </Result>
  <Result>
    <ac_name>60606508</ac_name>
    <obj_license>GHI890</obj_license>
  </Result>
</QueryResult>

Исходный документ:

D:\>type invoice.xml
<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
    <AdditionalDocumentReference>
        <ID>80186780</ID>
        <DocumentType>AKV</DocumentType>
    </AdditionalDocumentReference>
</Invoice>

D:\>

Таблица стилей:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name='QueryResult' select='document("lookup.xml")/Result'/>
    <xsl:template match='Invoice'>
        <Invoice>
            <xsl:apply-templates select='AdditionalDocumentReference'/>
        </Invoice>
    </xsl:template>

    <!-- By default, copy everything -->
    <xsl:template match="*|@*|text()|/">
        <xsl:copy>
            <xsl:apply-templates select="*|@*|text()"/>
        </xsl:copy>
    </xsl:template>

    <!-- AdditionalDocumentReference with documentType=AKV should be replaced 
        with AdditionalDocumentReference DocumentType=ABZ and the ID should 
        replaced with the correct obj_license --> 
    <xsl:template match="AdditionalDocumentReference[DocumentType='AKV']"> 
        <xsl:copy>
            <DocumentType>ABZ</DocumentType>
            <ID><xsl:value-of select='$QueryResult[@ac_name=current( )/ID]/@obj_license'/></ID>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Я что-то здесь делаю?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Если вы хотите использовать XSLT 1 (а ваша таблица стилей не использует какие-либо функции XSLT 2), тогда используйте version="1.0" в корневом элементе xsl:stylesheet или xsl:transform кода XSLT, поскольку я думаю, что libxslt в противном случае отказывается от запустите код.

Кроме того, если вы хотите выбрать элементы, а не атрибуты, вам нужны пути типа ac_name, а не @ac_name, поэтому исправьте

<xsl:value-of select='$QueryResult[@ac_name=current( )/ID]/@obj_license'/>

до

<xsl:value-of select='$QueryResult[ac_name=current( )/ID]/obj_license'/>

И другой путь тоже неверен, полная таблица стилей со всеми исправлениями

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name='QueryResult' select='document("test2018050202.xml")/QueryResult/Result'/>
    <xsl:template match='Invoice'>
        <Invoice>
            <xsl:apply-templates select='AdditionalDocumentReference'/>
        </Invoice>
    </xsl:template>

    <!-- By default, copy everything -->
    <xsl:template match="*|@*|text()|/">
        <xsl:copy>
            <xsl:apply-templates select="*|@*|text()"/>
        </xsl:copy>
    </xsl:template>

    <!-- AdditionalDocumentReference with documentType=AKV should be replaced 
        with AdditionalDocumentReference DocumentType=ABZ and the ID should 
        replaced with the correct obj_license --> 
    <xsl:template match="AdditionalDocumentReference[DocumentType='AKV']"> 
        <xsl:copy>
            <DocumentType>ABZ</DocumentType>
            <ID><xsl:value-of select='$QueryResult[ac_name = current()/ID]/obj_license'/></ID>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
0 голосов
/ 02 мая 2018

Существует несколько разных версий XSLT. Ваша таблица стилей имеет вкус версии 2,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

но модуль Perl, который вы используете для применения таблицы стилей XSLT, не поддерживает это.

xsl:version: only 1.0 features are supported

Похоже, вы уже знаете это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...