Пространство имен XSI скопировано в последовательность результатов - PullRequest
0 голосов
/ 11 мая 2018

У меня есть XML-файл, содержащий множество поисков.Ниже приведена упрощенная версия:

<?xml version="1.0" encoding="UTF-8"?>
<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">
    <Party name="Bens Birthday">
        <ZIP>AB1234</ZIP>
        <EMAIL>foo@bar.com</EMAIL>
        <ATTENDEES>
            <ATTENDEE>Bob</ATTENDEE>
            <ATTENDEE>David</ATTENDEE>
        </ATTENDEES>
    </Party>
</Parties>

Я написал простой XSD для проверки этих данных:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Parties">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Party" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="ZIP" minOccurs="0" maxOccurs="1" type="xs:string"/>
                            <xs:element name="EMAIL" minOccurs="0" maxOccurs="1" type="xs:string"/>
                            <xs:element name="ATTENDEES" minOccurs="0" maxOccurs="1">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="ATTENDEE" minOccurs="1" maxOccurs="unbounded" type="xs:string"/>
                                    </xs:sequence>
                                </xs:complexType>
                             </xs:element>
                        </xs:sequence>
                        <xs:attribute name="name" type="xs:string" use="required"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Это хорошо работает.

Я загружаюXML-файл в XSLT и использование его для поиска в преобразовании.

<xsl:variable name="party-details" select="document($party-file)/Parties"/>
<xsl:variable name="party-map" select="$party-details/Party[@name='Bens Birthday']"/>

Это хорошо работает, когда я опрашиваю текстовый узел:

<FOO>{$party-map/EMAIL}</FOO>

Но если япопробуйте сделать то же самое с последовательностью:

<xsl:sequence select="$party-map/ATTENDEES/ATTENDEE"/>

Я наследую определение пространства имен из XML-файла Party:

<Parties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/usr/local/share/xml/schema/quantile/Parties.xsd">

В результате получится следующий вывод:

<ATTENDEE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Bob</ATTENDEE>

Очевидно, что если я удаляю xmlns:xsi и xsi:noNamespaceSchemaLocation из XML-файла Party, проблема исчезнет ... но тогда я не проверю ее.

В конечном итоге это нарушит мою проверку вывода XSLTпоскольку определение xsi недопустимо для элемента ATTENDEE.

Я вроде вижу, что здесь происходит - все дочерние элементы Parties наследуют пространство имен xmlns: xsi, поэтому, когда я склеиваю ATTENDEEпоследовательность в моем выводе XSLT, отсутствие определения xsi в XSLT означает, что процессор добавляет его вЯ полагаю, он не делает этого для текстовых узлов, поскольку они не имеют понятия пространства имен, это несет только элемент.

Я могу переместить проблему, определив xmlns: xsi в другом месте выходного элемента иродительский элемент ATTENDEE в XSLT.

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

Есть идеи?Или, если кто-то может категорически сказать, что это невозможно, какие-либо другие предложения - например, вместо этого использовать DTD или полностью исключить схему из XML и, возможно, выполнить проверку внутри XSLT?Я догадываюсь сейчас!

1 Ответ

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

Не используйте xsl:sequence, затем используйте xsl:copy-of copy-namespaces="no", например.

<xsl:copy-of select="Parties/Party[@name = 'Bens Birthday']/ATTENDEES" copy-namespaces="no"/>

https://xsltfiddle.liberty -development.net / bdxtpU использует ваш образец в качестве основного входа, но, конечно, вы можете сделать то же самое с вашим <xsl:copy-of select="$party-map/ATTENDEES/ATTENDEE" copy-namespaces="no"/>.

...