2016-06-16 3 views
0

Я имею следующие входные данные как XML:XSLT-динамического пространства имен поколения элемент

<?xml version="1.0" encoding="UTF-8"?> 
 
<Header xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd" creator="mine"> 
 
    <SubHead1 values="1"> 
 
     <CoverPage> 
 
     <Number>324</Number> 
 
     <Status>test</Status> 
 
     <ChangeType>test</ChangeType> 
 
     <DescriptionOfChange>test</DescriptionOfChange> 
 
     <ReasonForChange>test</ReasonForChange> 
 
     <ReasonCode>test</ReasonCode> 
 
     <Workflow>test</Workflow> 
 
     </CoverPage> 
 
     <PageTwo> 
 
     <single1>No</single1> 
 
     <single2>No</single2> 
 
     <multisingle2> 
 
      <Value>r</Value> 
 
      <Value>i</Value> 
 
      <Value>h</Value> 
 
      <Value>m</Value> 
 
     </multisingle2> 
 
     <CreateUser>mine</CreateUser> 
 
     <Date01>2016-04-08T18:30:58Z</Date01> 
 
     </PageTwo> 
 
    </SubHead1> 
 
    <SubHead2 values="2"> 
 
     <TitleBlock> 
 
     <Number>22</Number> 
 
     <PartType>Part</PartType> 
 
     <LifecyclePhase>Preliminary</LifecyclePhase> 
 
     <Description>TEST</Description> 
 
     <Rev>88</Rev> 
 
     </TitleBlock> 
 
     <PageTwo> 
 
     <single1>z</single1> 
 
     <single2>a</single2> 
 
     <multisingle1> 
 
      <Value>b</Value> 
 
      <Value>c</Value> 
 
      <Value>d</Value> 
 
     </multisingle1> 
 
     <multisingle2> 
 
      <Value>7</Value> 
 
      <Value>ac</Value> 
 
     </multisingle2> 
 
     <single3>f</single3> 
 
     <CreateUser>mine</CreateUser> 
 
     <Date01>2016-04-27T17:31:44Z</Date01> 
 
     </PageTwo> 
 
    </SubHead2> 
 
</Header>

С ниже XSLT, я способен генерировать вывод:

<?xml version="1.0" encoding="UTF-8"?> 
 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd"> 
 
    <xsl:output method="xml" indent="yes" /> 
 
    <xsl:strip-space elements="*" /> 
 
    <xsl:template match="/*"> 
 
     <Header> 
 
     <SubHead2> 
 
      <xsl:attribute name="values"> 
 
       <xsl:value-of select="/*/*[2]/@values" /> 
 
      </xsl:attribute> 
 
      <xsl:apply-templates select="/*/*[2]/*[1]/*" /> 
 
      <xsl:for-each select="/*/*[2]/*[2]/*"> 
 
       <xsl:variable name="j" select="position()" /> 
 
       <xsl:if test="/*/*[2]/*[2]/*[$j] and not(/*/*[2]/*[2]/*[$j]/*)"> 
 
        <xsl:copy-of select="/*/*[2]/*[2]/*[$j]" /> 
 
       </xsl:if> 
 
       <xsl:for-each select="/*/*[2]/*[2]/*/*"> 
 
        <xsl:variable name="i" select="position()" /> 
 
        <xsl:if test="$i = 1"> 
 
        <xsl:apply-templates select="/*/*[2]/*/*[$j][*[2]]"> 
 
         <xsl:with-param name="testParam3" select="$i" /> 
 
        </xsl:apply-templates> 
 
        </xsl:if> 
 
       </xsl:for-each> 
 
      </xsl:for-each> 
 
      <SubHead1> 
 
       <xsl:apply-templates select="/*/*[1]/*[1]/*" /> 
 
      </SubHead1> 
 
     </SubHead2> 
 
     <xsl:for-each select="/*/*[2]/*[2]/*"> 
 
      <xsl:variable name="j" select="position()" /> 
 
      <xsl:for-each select="*"> 
 
       <xsl:variable name="i" select="position()" /> 
 
       <xsl:if test="$i &gt; 1"> 
 
        <xsl:call-template name="attr"> 
 
        <xsl:with-param name="testParam1" select="$j" /> 
 
        <xsl:with-param name="testParam2" select="$i" /> 
 
        </xsl:call-template> 
 
       </xsl:if> 
 
      </xsl:for-each> 
 
     </xsl:for-each> 
 
     </Header> 
 
    </xsl:template> 
 
    <xsl:template match="/*/*[2]/*/*[*[2]]"> 
 
     <xsl:copy> 
 
     <xsl:copy-of select="@* | *[1]" /> 
 
     </xsl:copy> 
 
    </xsl:template> 
 
    <xsl:template match="*"> 
 
     <xsl:copy-of select="." /> 
 
    </xsl:template> 
 
    <xsl:template match="/*/*[2]/*/*[*[2]]"> 
 
     <xsl:param name="testParam3" /> 
 
     <xsl:copy> 
 
     <xsl:copy-of select="@* | *[$testParam3]" /> 
 
     </xsl:copy> 
 
    </xsl:template> 
 
    <xsl:template name="attr"> 
 
     <xsl:param name="testParam1" /> 
 
     <xsl:param name="testParam2" /> 
 
     <SubHead2> 
 
     <xsl:attribute name="uniqueId"> 
 
      <xsl:value-of select="/*/*[2]/@values" /> 
 
     </xsl:attribute> 
 
     <Number> 
 
      <xsl:value-of select="/*/*[2]/*[1]/*[1]" /> 
 
     </Number> 
 
     <xsl:apply-templates select="/*/*[2]/*/*[$testParam1][*[2]]"> 
 
      <xsl:with-param name="testParam3" select="$testParam2" /> 
 
     </xsl:apply-templates> 
 
     </SubHead2> 
 
    </xsl:template> 
 
</xsl:stylesheet>

Output (XML):

<?xml version="1.0" encoding="UTF-8"?> 
 
<Header xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
 
    <SubHead2 values="2"> 
 
     <Number>22</Number> 
 
     <PartType>Part</PartType> 
 
     <LifecyclePhase>Preliminary</LifecyclePhase> 
 
     <Description>TEST</Description> 
 
     <Rev>88</Rev> 
 
     <single1>z</single1> 
 
     <single2>a</single2> 
 
     <multisingle1> 
 
      <Value>b</Value> 
 
     </multisingle1> 
 
     <multisingle2> 
 
      <Value>7</Value> 
 
     </multisingle2> 
 
     <single3>f</single3> 
 
     <CreateUser>mine</CreateUser> 
 
     <Date01>2016-04-27T17:31:44Z</Date01> 
 
     <SubHead1> 
 
      <Number>324</Number> 
 
      <Status>test</Status> 
 
      <ChangeType>test</ChangeType> 
 
      <DescriptionOfChange>test</DescriptionOfChange> 
 
      <ReasonForChange>test</ReasonForChange> 
 
      <ReasonCode>test</ReasonCode> 
 
      <Workflow>test</Workflow> 
 
     </SubHead1> 
 
    </SubHead2> 
 
    <SubHead2 uniqueId="2"> 
 
     <Number>22</Number> 
 
     <multisingle1> 
 
      <Value>c</Value> 
 
     </multisingle1> 
 
    </SubHead2> 
 
    <SubHead2 uniqueId="2"> 
 
     <Number>22</Number> 
 
     <multisingle1> 
 
      <Value>d</Value> 
 
     </multisingle1> 
 
    </SubHead2> 
 
    <SubHead2 uniqueId="2"> 
 
     <Number>22</Number> 
 
     <multisingle2> 
 
      <Value>ac</Value> 
 
     </multisingle2> 
 
    </SubHead2> 
 
</Header>

В выходных данных, как вы можете видеть, что я не в состоянии включить "создателю" атрибут в элементе "Заголовок"

Проблема в том, у меня есть нет контроля над входящим XML, поскольку значения пространств имен могут динамически возникать вместе с новыми атрибутами

Например: (Динамический корневой элемент)

<Header xmlns="http://www.oracle.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd" foo="bar">
<Header xmlns="http://www.ex.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.sample.com/ex/ http://www.sample.com/ex/foo.xsd">

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

Любая помощь будет полезна

Благодаря

ответ

0

если ты на самом деле хотел, чтобы справиться с XML-документы поступают с различными пространствами имен, что вы могли бы сделать, это сначала определить переменную для хранения URI пространства имен входящего документа (это предполагает, что XML-документ имеет только лишь пространство имен)

<xsl:variable name="namespace" select="namespace-uri(/*)" /> 

Тогда вместо того, чтобы делать <Header>, чтобы создать элемент, используйте xsl:element и указать пространство имен

<xsl:element name="Header" namespace="{$namespace}"> 

вы должны сделать это для каждого статического элемента вы создаете

Попробуйте упрощенную XML в качестве примера

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:strip-space elements="*" /> 
    <xsl:variable name="namespace" select="namespace-uri(/*)" /> 

    <xsl:template match="/*"> 
     <xsl:element name="Header" namespace="{$namespace}"> 
     <xsl:copy-of select="namespace::*" /> 
     <xsl:copy-of select="@*" /> 
     <xsl:element name="SubHead2" namespace="{$namespace}"> 
      <xsl:attribute name="values"> 
       <xsl:value-of select="/*/*[2]/@values" /> 
      </xsl:attribute> 
     </xsl:element> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Спасибо за вышеуказанный код. Но он не отображает все атрибуты в '

', он выбирает только часть 'xmlns', оставшаяся часть отбрасывается. – nawazlj

+0

Я изменил свой ответ, чтобы включить строку для копирования атрибутов элемента '

'. Обратите внимание, что 'xmlns' не находится в атрибуте. Это декларация пространства имен и обрабатывается совершенно по-другому. –

+0

Еще раз спасибо, и он пропустил 'xmlns: xsd' в'

'часть, по которой, когда я использую' apply-templates', тогда 'xmlns: xsd' входит во все подэлементы – nawazlj

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