Как не копировать атрибут в выводе XSLT 2.0

Я хочу преобразовать одно сообщение XML в другое. Мое входное сообщение в настоящее время содержит несколько пустых элементов с атрибутами @ nil = ture value. Я хочу, чтобы эти элементы были созданы пустыми, но без атрибута nill. Пожалуйста, смотрите ниже мой текущий прогресс:

Ввод XML:

<?xml version="1.0" encoding="UTF-8"?>
    <collection>
        <row>
            <nr>A00</nr>
            <type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
        </row>
        <row>
            <nr>A01</nr>
            <type>mash</type>
        </row>
    </collection>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:template match="//*[local-name()='collection']">
        <jsonArray>
            <xsl:text disable-output-escaping="yes">&lt;?xml-multiple?&gt;</xsl:text>
            <xsl:for-each select="//*[local-name()='row']">
                <jsonObject>
                     <xsl:copy-of select="node() except @nil" />
                </jsonObject>
            </xsl:for-each>
        </jsonArray>
    </xsl:template>
</xsl:stylesheet>

Текущий выход:

<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
   <?xml-multiple?>
   <jsonObject>
      <nr>A00</nr>
      <type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
   </jsonObject>
   <jsonObject>
      <nr>A01</nr>
      <type>mash</type>
   </jsonObject>
</jsonArray>

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

<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
   <?xml-multiple?>
   <jsonObject>
      <nr>A00</nr>
      <type/>
   </jsonObject>
   <jsonObject>
      <nr>A01</nr>
      <type>mash</type>
   </jsonObject>
</jsonArray>

person omer khalid    schedule 15.07.2019    source источник


Ответы (1)


Когда вы делаете <xsl:copy-of select="node() except @nil" />, вы копируете дочерние элементы текущего row, который копирует их без изменений. except @nil не будет делать то, что вы ожидаете, потому что он будет искать атрибуты с именем @nil в текущем row элементе (и в любом случае атрибут, который вы ищете, @xsi:nil.

Вместо этого замените xsl:copy-of на xsl:apply-templates и добавьте шаблон удостоверения в свой XSLT (с небольшой настройкой для удаления объявлений пространств имен).

<xsl:template match="@*|node()">
    <xsl:copy copy-namespaces="no">
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

Тогда вам просто нужен шаблон, чтобы игнорировать xsl:type

    <xsl:template match="@xsi:nil" />

Попробуйте этот XSLT

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="xsi">

    <xsl:template match="@*|node()">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@xsi:nil" />

    <xsl:template match="//*[local-name()='collection']">
        <jsonArray>
            <xsl:processing-instruction name="xml-multiple" />
            <xsl:for-each select="//*[local-name()='row']">
                <jsonObject>
                     <xsl:apply-templates select="@*|node()" />
                </jsonObject>
            </xsl:for-each>
        </jsonArray>
    </xsl:template>
</xsl:stylesheet>

(Обратите внимание, вы действительно должны использовать xsl:processing-instruction для создания инструкций по обработке).

person Tim C    schedule 15.07.2019