Пустое пространство имен в дочернем узле - PullRequest
0 голосов
/ 27 апреля 2018

При использовании фиксированного пространства имен вывод правильный.

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml"/>
    <xsl:template match="/NewDataSet">
        <Foo namespace="http://MyLink/FixedVersion">
            <Bar>
                <SomeData/>
            </Bar>
        </Foo>
    </xsl:template>
</xsl:stylesheet>

Выход:

<?xml version="1.0" encoding="utf-8"?>
<Foo namespace="http://MyLink/FixedVersion">
    <Bar>
        <SomeData />
    </Bar>
</Foo>

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

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml"/>
    <xsl:template match="/NewDataSet">
        <xsl:element name="Foo" namespace="http://MyLink/{Table/version}">
            <Bar>
                <SomeData/>
            </Bar>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Выход:

<?xml version="1.0" encoding="utf-8"?>
<Foo xmlns="http://MyLink/v02_04_01">
    <Bar xmlns="">
        <SomeData />
    </Bar>
</Foo>

https://stackoverflow.com/a/49872085/2524586 утверждает, что они находятся в разных пространствах имен, но я не понимаю, как фиксированное и динамическое значение может изменить это.

Мой ожидаемый результат - первый вывод, но с динамическим значением version.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Расширенное имя элемента (то есть пара (пространство имен, локальное имя)) полностью определяется инструкцией, которая создает элемент; это никак не зависит от родительского элемента в дереве результатов. Вы никогда не можете полагаться на элемент, входящий в то же пространство имен, что и его родитель.

Для буквального элемента результата, такого как <Foo> или <p:Bar>, расширенное имя элемента в дереве результатов совпадает с расширенным именем элемента в таблице стилей. То есть это определяется правилами спецификации пространств имен XML: URI пространства имен определяется объявлениями пространства имен xmlns в таблице стилей (которые могут появляться в самом элементе буквального результата или в любом элементе-предке). Это, в свою очередь, означает, что пространство имен является статической константой, оно не может быть вычислено динамически.

Для элемента, созданного с использованием xsl: element, существует два способа задания пространства имен. Если присутствует атрибут namespace, то его эффективное значение (интерпретируемое как AVT) устанавливает URI пространства имен сконструированного элемента. Поскольку это AVT, пространство имен может быть вычислено динамически.

При отсутствии атрибута namespace значение атрибута name интерпретируется как лексическое QName, а пространство имен определяется так же, как и для литерального элемента результата, с использованием объявлений пространства имен, которые находятся в область действия для инструкции xsl:element в таблице стилей. С помощью этого механизма вы можете динамически выбирать между фиксированным набором статически известных пространств имен, но вы не можете вычислить пространство имен полностью динамически:

<xsl:stylesheet xmlns:a="http://one-uri/" xmlns:b="http://another-uri/">
....
   <xsl:element name="{if (x) then 'a' else 'b'}:foo">
0 голосов
/ 27 апреля 2018

Кажется, вы должны явно создавать пространства имен для каждого элемента. Ваша ошибка в первом примере состояла в том, что вы вообще не создали пространство имен:

<Foo namespace="http://MyLink/FixedVersion">
    <Bar>
        <SomeData />
    </Bar>
</Foo>

Здесь Foo не назначено пространство имен:
видите, у него нет xmlns="..." атрибута пространства имен (!), но (скорее произвольный) namespace="..." атрибут.

Таким образом, единственный способ достичь желаемого результата - добавить атрибут namespace="..." к каждому xsl:element:

<xsl:template match="/NewDataSet">
    <xsl:element name="Foo" namespace="http://MyLink/{Table/version}">
        <xsl:element name="Bar" namespace="http://MyLink/{Table/version}">
            <xsl:element name="SomeData" namespace="http://MyLink/{Table/version}" />
        </xsl:element>
    </xsl:element>
</xsl:template>

Вывод:

<?xml version="1.0"?>
<Foo xmlns="http://MyLink/v02_04_01">
    <Bar>
        <SomeData/>
    </Bar>
</Foo>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...