Вставка статического значения пространства имен в XML - PullRequest
0 голосов
/ 24 апреля 2019

Я пишу сценарий XSLT, и моя цель состоит в том, чтобы вставить пространство имен (http://www.COMP.com/upp/readxml/09) с корневым элементом. Я написал несколько вариантов, и 2 моих кода частично разрешают его.

  1. XSLT-код AB - этот код вставляет пространство имен, но все значения атрибутов объединяются и теги не предоставляются.
  2. XSLT Code PQ - этот код вставляет пространство имен, но изменяет иерархию второго узла и помещает его в качестве корневого элемента.

CODE AB:

<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:tns="http://www.COMP.com/upp/readxml/09">
    <xsl:output method="xml"/>
    <xsl:template match="*">
        <xsl:variable name="elname">
            <xsl:text disable-output-escaping="yes">tns:</xsl:text>
            <xsl:value-of select="local-name()"/>
        </xsl:variable>     
                <xsl:element name="tns:{local-name()}">
                    <xsl:apply-templates select="@* | node()"/>             
                </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Код PQ:

<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
    <xsl:output method="xml"/>
    <xsl:template match="*" priority="1">
        <xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
         <xsl:copy-of copy-namespaces="no" select="*[local-name() != 'RootDocument']"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

ВХОД XML:

<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
    <System Id="GOLD" />
    <Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
    <Timezone Id="UTC" />   
    <CorrelationID Id="" />
  </Header>
 <Channels> 
    <Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
      <ChannelID ID="LC:2A" />     
    </Channel>
  </Channels>
</RootDocument>

ОЖИДАЕМЫЙ выходной XML:

<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
    <System Id="GOLD" />
    <Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
    <Timezone Id="UTC" />   
    <CorrelationID Id="" />
  </Header>
 <Channels> 
    <Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
      <ChannelID ID="LC:2A" />     
    </Channel>
  </Channels>
</RootDocument>

OR

<?xml version="1.0" encoding="us-ascii" standalone="yes"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09">
<Header>
    <System Id="GOLD" />
    <Creation_Datetime Datetime="2019-02-19T17:53:38Z" />
    <Timezone Id="UTC" />   
    <CorrelationID Id="" />
  </Header>
 <Channels> 
    <Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
      <ChannelID ID="LC:2A" />     
    </Channel>
  </Channels>
</RootDocument>

Подскажите, пожалуйста, как правильно получить атрибут в XML или каким-либо другим способом просто вставить пространство имен, сохранив остальную часть XML таким же.

Ответы [ 4 ]

0 голосов
/ 24 апреля 2019

Спасибо всем за ответ на мой запрос. Все вышеперечисленные решения работают, и в то же время я тоже пытался, и это то, что я разработал, что также дает желаемый результат.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*" priority="1">
        <xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
0 голосов
/ 24 апреля 2019

Вы можете использовать следующие шаблоны для получения второй версии желаемого результата:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
          <xsl:apply-templates select="node()|@*" />
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:copy select="@*" />
    </xsl:template>

</xsl:stylesheet>

Вывод:

<?xml version="1.0"?>
<RootDocument xmlns="http://www.COMP.com/upp/readxml/09">
    <Header>
        <System Id="GOLD"/>
        <Creation_Datetime Datetime="2019-02-19T17:53:38Z"/>
        <Timezone Id="UTC"/>
        <CorrelationID Id=""/>
    </Header>
    <Channels>
        <Channel StartDate="2019-01-01T00:00:00-05:00" EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
            <ChannelID ID="LC:2A"/>
        </Channel>
    </Channels>
</RootDocument>
0 голосов
/ 24 апреля 2019

Минималистская версия:

XSLT 1.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="us-ascii" standalone="yes" indent="yes"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="http://www.COMP.com/upp/readxml/09">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Это даст второй результат, показанный в вашем вопросе. Чтобы получить 1-й вывод (с его избыточными объявлениями пространства имен), измените:

<xsl:copy-of select="@*"/>

до:

<xsl:copy-of select="@* | namespace::*"/>
0 голосов
/ 24 апреля 2019

Вы преобразовываете элементы в пустом пространстве имен в некоторое фиксированное пространство имен. Так что эта таблица стилей

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[namespace-uri()='']">
        <xsl:element name="{name()}" namespace="http://www.COMP.com/upp/readxml/09">
            <xsl:copy-of select="namespace::*"/>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Выход:

<RootDocument xmlns="http://www.COMP.com/upp/readxml/09"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Header>
    <System Id="GOLD"/>
    <Creation_Datetime Datetime="2019-02-19T17:53:38Z"/>
    <Timezone Id="UTC"/>
    <CorrelationID Id=""/>
  </Header>
  <Channels>
    <Channel StartDate="2019-01-01T00:00:00-05:00" 
             EndDate="2019-02-01T00:00:00-05:00" TimeZone="EasternUS">
      <ChannelID ID="LC:2A"/>
    </Channel>
  </Channels>
</RootDocument>

Заметьте : namespace ось устарела с XPath 2.0, что означает "Если режим совместимости с XPath 1.0 имеет значение false, поддержка оси пространства имен определяется реализацией" Таким образом, вы можете получить ожидаемый результат во втором формате. На практике мне известен только один XSLT-процессор, который не поддерживает ось namespace: внутренний XSLT-процессор Mozilla Firefox, в котором не реализована ось namespace, даже если это только XSLT. 1.0 процессор.

...