2015-11-23 2 views
2

Я перехожу из одного документа XML в другой XML-документ с помощью XSLT. Оба типа входных и выходных документов находятся в разных пространствах имен по умолчанию. Я использовал сначала преобразование, а затем фильтр с JAXB в отношении выходной схемы. Мое требование: если издатель/каталог/cd11/year доступен/существует во входном xml, то новый элемент со значением необходимо создать как издатель/каталог/cd22 = 'Новая версия' в xml. (fyi. publisher/catalog/cd22 существует в схеме вывода)XSLT для копирования элемента без использования по умолчанию/старого пространства имен

Проблема: когда я трансформируюсь с использованием приведенного ниже XSLT, создается новый узел с пространством имен выходных данных, но родительский узел добавляется с входным пространством имен xml/path-default-namespace (http://www.altova.com), я не уверен, почему это добавляется, но я уверен, что JAXB фильтрует это на желаемый результат.

Может ли кто-нибудь помочь в этом?

Входной XML:

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns="http://www.altova.com"> 
    <publisher> 
     <Name id="d123"> 
      <Location>Chicago</Location> 
     </Name> 
     <catalogue id="d1" > 
      <cd11 id="d2"> 
       <title>Empire Burlesque</title> 
       <artist>Bob Dylan</artist> 
       <year>1985</year> 
      </cd11> 
     </catalogue> 
     <catalogue id="d3" > 
      <cd11 id="d4"> 
       <title>Jurassic World</title> 
       <artist>Chris Pratt</artist> 
      </cd11> 
     </catalogue>  
    </publisher> 
</root> 

XSLT:

<xsl:stylesheet version="2.0" xpath-default-namespace="http://www.altova.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" > 

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

    <xsl:template match="catalogue[string(cd11/year)]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <xsl:element name="cd22" > 
     <xsl:value-of select="'New Release'" /> 
    </xsl:element> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

После преобразования

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns="http://example.com/"> 
    <publisher> 
     <Name id="d123"> 
      <Location>Chicago</Location> 
     </Name> 
     <catalogue xmlns="http://www.altova.com" id="d1" > 
      <cd11 xmlns="http://example.com/" id="d2"> 
       <title>Empire Burlesque</title> 
       <artist>Bob Dylan</artist> 
       <year>1985</year> 
      </cd11> 
      <cd22 xmlns="http://example.com/">New Release</cd22> 
     </catalogue> 
     <catalogue id="d3" > 
      <cd11 id="d4"> 
       <title>Jurassic World</title> 
       <artist>Chris Pratt</artist> 
      </cd11> 
     </catalogue>  
    </publisher> 
</root> 

неправильный выход: После того, как фильтр с JAXB против выходной схемы, которая имеет пространство имен, как Xmlns =» http://example.com/ ">

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns="http://example.com/"> 
    <publisher> 
     <Name id="d123"> 
      <Location>Chicago</Location> 
     </Name> 
     <catalogue id="d3" > 
      <cd11 id="d4"> 
       <title>Jurassic World</title> 
       <artist>Chris Pratt</artist> 
      </cd11> 
     </catalogue>  
    </publisher> 
</root> 

Желаемая Выходной XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns="http://example.com/"> 
    <publisher> 
     <Name id="d123"> 
      <Location>Chicago</Location> 
     </Name> 
     <catalogue id="d1" > 
      <cd11 id="d2"> 
       <title>Empire Burlesque</title> 
       <artist>Bob Dylan</artist> 
       <year>1985</year> 
      </cd11> 
      <cd22>New Release</cd22> 
     </catalogue> 
     <catalogue id="d3" > 
      <cd11 id="d4"> 
       <title>Jurassic World</title> 
       <artist>Chris Pratt</artist> 
      </cd11> 
     </catalogue>  
    </publisher> 
</root> 

ответ

0

Как бы просто это:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output standalone="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pNewNS" select="'http://example.com/'"/> 
<xsl:variable name="vOldNS" select="namespace-uri(/*)"/> 

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

    <xsl:template match="*[namespace-uri() eq $vOldNS]"> 
    <xsl:element name="{name()}" namespace="{$pNewNS}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template priority="3" match="*[@id eq 'd1']/*[*[name() = 'year']]"> 
    <xsl:next-match/> 
    <xsl:element name="cd22" namespace="{$pNewNS}">New Release</xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом XML документа:

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns="http://www.altova.com"> 
    <publisher> 
     <Name id="d123"> 
      <Location>Chicago</Location> 
     </Name> 
     <catalogue id="d1" > 
      <cd11 id="d2"> 
       <title>Empire Burlesque</title> 
       <artist>Bob Dylan</artist> 
       <year>1985</year> 
      </cd11> 
     </catalogue> 
     <catalogue id="d3" > 
      <cd11 id="d4"> 
       <title>Jurassic World</title> 
       <artist>Chris Pratt</artist> 
      </cd11> 
     </catalogue>  
    </publisher> 
</root> 

разыскиваемых, правильный результат получается:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root xmlns="http://example.com/"> 
    <publisher> 
     <Name id="d123"> 
     <Location>Chicago</Location> 
     </Name> 
     <catalogue id="d1"> 
     <cd11 id="d2"> 
      <title>Empire Burlesque</title> 
      <artist>Bob Dylan</artist> 
      <year>1985</year> 
     </cd11> 
     <cd22>New Release</cd22> 
     </catalogue> 
     <catalogue id="d3"> 
     <cd11 id="d4"> 
      <title>Jurassic World</title> 
      <artist>Chris Pratt</artist> 
     </cd11> 
     </catalogue> 
    </publisher> 
</root> 

Объяснение:

  1. Читайте и узнать о <xsl:element> инструкции.

  2. Прочитайте и узнайте о функции namespace-uri().

  3. Читайте и изучайте инструкцию <xsl:next-match>. Очень мало людей знают об этой инструкции и о том, насколько мощным и полезным она может быть.

+0

Спасибо за ваше решение. Но вы претерпели мои условия для применения?Если издатель/каталог/cd11/year доступен/существует во входном xml, то новый элемент со значением необходимо создать как издатель/каталог/cd22 = 'Новая версия' в выставляемом xml –

+0

@ GJ_15, я отредактировал решение и он теперь отвечает вашим точным требованиям. –

+0

@ Dimitre, Да, это работает для меня. И я немного изменил XSLT, сопоставив имя узла вместо атрибута. Огромное спасибо. Это мне очень помогло. –

Смежные вопросы