Как я могу заменить XML префиксы пространства имен встроенными объявлениями xmlns? - PullRequest
2 голосов
/ 07 февраля 2020

У меня есть два XML объекта, которые, как мне кажется, описывают одну и ту же сущность, один использует префиксы пространства имен, а другой использует встроенные объявления пространства имен. Я хочу использовать их, но различные способы представления пространства имен делают это практически невозможным.

Как взять первый xml фрагмент ниже и изменить его так, чтобы он соответствовал второму фрагменту?

<!--I want to take data that looks like this-->
<Foo xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
  <e:Description></e:Description>
  <e:Name i:nil="true"></e:Name>
  <e:DisplaySeqNo>0</e:DisplaySeqNo>
</Foo>

<!--I want to make that data that looks like this-->
<Foo>
  <Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Description>
  <Name i:nil="true" xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"></Name>
  <DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>

Требование их различения является частью процесса отладки вручную, поэтому я был бы счастлив с веб-инструментом, скриптом или чем-то еще. Я не планирую делать это регулярно, но рву свои волосы, пытаясь выяснить, чем xml образец А отличается от xml образца Б.

1 Ответ

2 голосов
/ 07 февраля 2020

Вы можете использовать следующую таблицу стилей XSLT-1.0. Это комбинация шаблона Identity (который копирует все узлы) с двумя шаблонами, обрабатывающими ситуацию замены:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:e="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="Foo">
      <xsl:element name="{local-name()}" namespace="">
        <xsl:apply-templates select="node()|@*" />
      </xsl:element>
    </xsl:template>

    <xsl:template match="e:*">
      <xsl:element name="{local-name()}" namespace="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">
        <xsl:apply-templates select="node()|@*" />
      </xsl:element>
    </xsl:template>    

</xsl:stylesheet>

Выходные данные:

<Foo>
  <Description xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo"/>
  <Name xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo" i:nil="true"/>
  <DisplaySeqNo xmlns="http://schemas.cch.com/FooBar/MDS/2007/12/04/Foo">0</DisplaySeqNo>
</Foo>

Это также выдает ошибку для файла XML, поскольку в нем не определено пространство имен i. Он также копирует комментарий из ввода XML, но я думаю, что это был просто комментарий для иллюстрации, и поэтому его можно игнорировать.

Если вы используете какой-то Linux, вы можете легко передать этот шаблон для xsltproc.

...