2015-02-24 5 views
1

У меня есть XML с дочерними узлами, которые я хочу, чтобы они отображались на уровне родительского уровня с использованием XSL. Мой XML не очень прост, и мои знания XSL не очень хороши. Я буду отличным, если кто-нибудь может предоставить мне решение.Перемещение дочернего узла на родительский уровень с использованием XML

Мой образец XML выглядит следующим образом:

<env:Envelope 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
    <env:Body> 
    <DPSretrieveResponse 
     xmlns="https://tpvs.hmrc.gov.uk/dps"> 
     <DPSdata 
     xmlns="http://www.govtalk.gov.uk/taxation/DPSwrapper/1"> 
     <DPSheader> 
      <Service>PAYE</Service> 
      <EntityType>EmpRef</EntityType>   
     </DPSheader>   
     <CodingNoticesP6P6B FormType="P6B" IssueDate="2008-05-06" SequenceNumber="1375" TaxYearEnd="2009" 
      xmlns="http://www.govtalk.gov.uk/taxation/CodingNoticesP6P6B/2"> 
      <EmployerRef>123/A6</EmployerRef> 
      <Name> 
      <Title>MR</Title> 
      <Forename>J V</Forename> 
      <Surname>Scanlon</Surname> 
      </Name> 
      <WorksNumber>SCA/466</WorksNumber> 
      <CodingUpdate> 
      <TaxCode>NT</TaxCode> 
      </CodingUpdate> 
     </CodingNoticesP6P6B> 
     </DPSdata> 
    </DPSretrieveResponse> 
    </env:Body> 
</env:Envelope> 

Что требуется, это:

<env:Envelope 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <env:Body> 
    <DPSretrieveResponse 
     xmlns="https://tpvs.hmrc.gov.uk/dps"> 
     <DPSdata 
     xmlns="http://www.govtalk.gov.uk/taxation/DPSwrapper/1"> 
     <DPSheader> 
      <Service>PAYE</Service> 
      <EntityType>EmpRef</EntityType>   
     </DPSheader>   
     <CodingNoticesP6P6B FormType="P6B" IssueDate="2008-05-06" SequenceNumber="1375" TaxYearEnd="2009" 
      xmlns="http://www.govtalk.gov.uk/taxation/CodingNoticesP6P6B/2"> 
      <EmployerRef>123/A6</EmployerRef> 
      <Name>   
      </Name> 
      <Title>MR</Title> 
      <Forename>J V</Forename> 
      <Surname>Scanlon</Surname> 
      <WorksNumber>SCA/466</WorksNumber> 
      <CodingUpdate> 
      <TaxCode>NT</TaxCode> 
      </CodingUpdate> 
     </CodingNoticesP6P6B> 
     </DPSdata> 
    </DPSretrieveResponse> 
    </env:Body> 
</env:Envelope> 

Просто, название, имя и фамилия под имя тега нужно показывать в том же уровне, что и имя ;

<Name>   
</Name> 
<Title>MR</Title> 
<Forename>J V</Forename> 
<Surname>Scanlon</Surname> 

Любые советы приветствуются.

спасибо.

+0

Что вы пробовали до сих пор, и как делает вывод, который вы» теперь вы теперь отличаетесь от того, что вам нужно? Не могли бы вы отредактировать вопрос, чтобы показать свой текущий XSLT? –

+0

Если у вас есть один шаблон идентификации (чтобы скопировать все узлы), создайте второй, который выберет элемент 'Name' (возможно, префикс его с соответствующим пространством имен), содержащий только' '. Он переместит детей «Name» в место, где раньше был элемент «Name». – helderdarocha

+0

Кроме того, нам нужно знать, что _version_ XSLT вы используете. У вас есть доступ к версии 2.0 или более поздней версии, или вы ограничены только 1.0? –

ответ

0

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

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

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

<xsl:template match="env:Envelope"> 
    <xsl:copy> 
     <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'" /> 
     <xsl:namespace name="soapenc" select="'http://schemas.xmlsoap.org/soap/encoding/'" /> 
     <xsl:namespace name="xsd" select="'http://www.w3.org/2001/XMLSchema'" /> 
     <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 

Наконец, для перемещения детей Name на один уровень вверх, сначала нужно объявить пространство имен, где Name принадлежит:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
... xmlns:ns0="http://www.govtalk.gov.uk/taxation/CodingNoticesP6P6B/2"> 

, чтобы вы могли определить соответствие с префиксом, который вы указали. Тогда вы просто позвоните <apply-templates/> на ребенок без копирования текущего элемента:

<xsl:template match="ns0:Name"> 
    <xsl:apply-templates /> 
</xsl:template> 

Вот полная таблица стилей, которая должна работать:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:ns0="http://www.govtalk.gov.uk/taxation/CodingNoticesP6P6B/2" 
    exclude-result-prefixes="ns0" 
    version="2.0"> 

    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="env:Envelope"> 
     <xsl:copy> 
      <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'" /> 
      <xsl:namespace name="soapenc" select="'http://schemas.xmlsoap.org/soap/encoding/'" /> 
      <xsl:namespace name="xsd" select="'http://www.w3.org/2001/XMLSchema'" /> 
      <xsl:apply-templates /> 
     </xsl:copy> 
    </xsl:template> 

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

    <xsl:template match="ns0:Name"> 
     <xsl:apply-templates /> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Фантастический! Он работает отлично. Большое спасибо за любезную помощь. –