xslt - ссылка на документ в xsl: element - PullRequest
0 голосов
/ 12 января 2011

я хочу сослаться на внешний xml в xls в элементе

<xsl:element name="{document('mapping.xml', /)/mappings/column/[@id=name()]}" >

Возможно ли это?

Обновление

mapping.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
      <columns>
        <column id="path">path</column>
      </columns>
</mappings>

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

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:dms="http://www.news.at/dms">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:variable name="Mapping" select="document('mapping.xml', /)" />

    <xsl:template match="/">
        <xsl:element name="document">
            <xsl:for-each select="document/*">

            <xsl:element name=
  "{$Mapping/mappings/columns/column[@id = name(current())]}" />


                <xsl:element name="item" >

                <xsl:attribute name="id">
                <xsl:if test="not($Mapping/mappings/columns/column[@id= name(current())])">
                    <xsl:message>Markup Error: no id attribute in <xsl:value-of select="name(current())" /></xsl:message>
               </xsl:if>        
                        <xsl:value-of select="$Mapping/mappings/columns/column[@id= name(current())]" /></xsl:attribute>
                    <xsl:value-of select="text()" />
                </xsl:element>
            </xsl:for-each>     
        </xsl:element>
    </xsl:template>


</xsl:stylesheet>

Input.xml

<?xml version="1.0" encoding="UTF-8" ?>
<document>
   <path>sdfsdfsdf</path>
</document>

Спасибо!

Ответы [ 2 ]

1 голос
/ 12 января 2011

я хочу сослаться на внешний xml в xls в элементе

<xsl:element name=
 "{document('mapping.xml', /)/mappings/column/[@id=name()]}" >

Да, атрибут name инструкции <xsl:element> допускает AVT (Шаблон атрибута-значения s )

У предоставленного кода есть ряд проблем :

  1. Существует очевидноесинтаксическая ошибка в предоставленном вами коде:

    document('mapping.xml', /)/mappings/column/[@id=name()]

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

.2. В приведенном выше выражении нет ничего, что относится к текущему узлу в исходном XML-документе .Я предполагаю, что предикат

[@id=name()]

должен быть примерно таким:

[@id=name(current())]

Итак, я предполагаю, чтовы можете захотеть что-то вроде :

 <xsl:element name=
  "{document('mapping.xml', /)/mappings/column[@id=name(current())]}" >

Может быть дополнительная, третья проблема: (подтверждено в комментарии ОП как реальная проблема):

Выражение, указанное как AVT в атрибуте name выше, может иметь строковое значение, которое не является синтаксически допустимым QName.Примеры недопустимых значений sych: 123 или A B

В этом случае возможны различные решения :

  • Использовать строковое значение другого узла(измените выражение XPath).
  • Преобразуйте нарушающие символы в допустимый символ:

...

concat(
       translate(substring(yourExpression,1,1), 
                 $illegalFirstCharacters, 
                 '________________'),
       translate(substring(yourExpression,2),
                 $illegalCharacters,
                 '________________')
       )

, где $illegalFirstCharacters - переменнаяопределяется как содержащий все возможные символы, которые могут встречаться в качестве первого символа и которые не допускаются в качестве первого символа QName *. 1069 *

и $illegalCharacters - это переменная, определенная, чтобы содержать все возможные символы, которые могут появляться послепервый символ и не допускается, как в QName после его первого символа.

По существу, $illegalFirstCharacters - это конкатенация $illegalCharacters и строки "0123456789".

Последний аргументtranslate() выше должно быть достаточно длинным, чтобы вместить по одному _ для каждого возможного недопустимого символа.

Это преобразование в действительное QName может быть выражено намного проще в XPath 2.0 (XSLT 2.0) использование регулярных выражений.

Это решение, конечно, следует применять с осторожностью, поскольку в зависимости от фактических данных возможно преобразование двух разных значений, содержащих недопустимые символы QNAme, втот же QName.

1 голос
/ 12 января 2011

Да, абсолютно.Вот так:

<xsl:element name="{normalize-space(
  document('mapping.xml', /)/mappings/column[@id=name(current())]
)}" >

На простом английском: это выберет любой <column> в пределах /mappings, чей @id равен имени текущего элемента в XSLT.Текстовое значение этого столбца будет обрезано с помощью normalize-space() и станет новым <xsl:element> именем.

(Обратите внимание, что comumn[@id=name()] означает «любой столбец, чье @id равно его имени»", и, следовательно, соответствует только <column id="column">. Функция current() необходима для того, что вы хотите.)

Однако было бы полезно сначала сохранить документ в глобальной переменной:

<!-- at the <xsl:stylesheet> level... -->
<xsl:variable name="mappings" 
  select="document('mapping.xml', /)/mappings/column" 
/>

<!-- later, anywhere... -->
<xsl:element name="{ normalize-space($mappings[@id=name(current())]) }" >
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...