Преобразование XSL для каждого не работает

Пожалуйста, ребята, не могли бы вы помочь мне с преобразованием xsl. Я пробовал все, но это не работает. Исходник xml:

<ROWSET>
 <ROW>
  <ID>111</ID>
  <F_I>11</F_I>
  <NAME>sometext</NAME>
  <CODE>text</CODE>      
  <CARD_PRODUCTS>
   <CARD_PRODUCTS_ROW>
    <ID>111</ID>
    <F_I>11</F_I>
    <NAME>text</NAME>
    <CODE>text</CODE>        
   </CARD_PRODUCTS_ROW>
   <CARD_PRODUCTS_ROW>
    <ID>111</ID>
    <F_I>11</F_I>
    <NAME>text</NAME>
    <CODE>text</CODE>        
   </CARD_PRODUCTS_ROW>
   ...
  </CARD_PRODUCTS>
 </ROW>
</ROWSET>

Его нужно преобразовать (схема 1:1, просто переименованные элементы) из:

<xs:element name="ROWSET" type="mule:ROWSET"/>
   <xs:complexType name="ROWSET">
      <xs:sequence>
         <xs:element name="ROW" type="mule:ROW" maxOccurs="unbounded"/>         
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="ROW">
      <xs:sequence>
         <xs:element name="ID" type="xs:string"/>
         <xs:element name="F_I" type="xs:string"/>
         <xs:element name="NAME" type="mule:string256"/>
         <xs:element name="CODE" type="mule:CODE"/>             
         <xs:element name="CARD_PRODUCTS" type="mule:CARD_PRODUCTS"/>
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="CARD_PRODUCTS">
      <xs:sequence>
         <xs:element name="CARD_PRODUCTS_ROW" type="mule:CARD_PRODUCTS_ROW" maxOccurs="unbounded"/>
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="CARD_PRODUCTS_ROW">
      <xs:sequence>
         <xs:element name="ID" type="xs:string"/>
         <xs:element name="F_I" type="xs:string"/>
         <xs:element name="NAME" type="mule:string256"/>
         <xs:element name="CODE" type="mule:CODE"/>             
      </xs:sequence>
   </xs:complexType>

to:

<xs:element name="SalaryProducts" type="sapr:SalaryProducts"/>
   <xs:complexType name="SalaryProducts">
      <xs:sequence>
         <xs:element name="SalaryProduct" type="sapr:SalaryProduct" maxOccurs="unbounded"/>         
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="SalaryProduct">
      <xs:sequence>
         <xs:element name="id" type="xs:string"/>
         <xs:element name="finInstId" type="xs:string"/>
         <xs:element name="name" type="sapr:string256"/>
         <xs:element name="productCode" type="sapr:productCode"/>
         <xs:element name="CardProducts" type="sapr:CardProducts"/>
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="CardProducts">
      <xs:sequence>
         <xs:element name="CardProduct" type="sapr:CardProduct" maxOccurs="unbounded"/>
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="CardProduct">
      <xs:sequence>
         <xs:element name="id" type="xs:string"/>
         <xs:element name="finInstId" type="xs:string"/>
         <xs:element name="name" type="sapr:string256"/>
         <xs:element name="productCode" type="sapr:productCode"/>             
      </xs:sequence>
   </xs:complexType>

XSLT:

<?xml version="1.0" encoding="UTF-8" ?>

   <xsl:template match="/">
      <tns:SalaryProducts>
         <xsl:for-each select="/ns0:ROWSET/ns0:ROW">
            <tns:SalaryProduct>
               <tns:id>
                  <xsl:value-of select="ns0:ID"/>
               </tns:id>
               <tns:finInstId>
                  <xsl:value-of select="ns0:F_I"/>
               </tns:finInstId>
               <tns:name>
                  <xsl:value-of select="ns0:NAME"/>
               </tns:name>
               <tns:productCode>
                  <xsl:value-of select="ns0:CODE"/>
               </tns:productCode>                   
               <tns:CardProducts>
                  <xsl:for-each select="/ns0:ROWSET/ns0:ROW/ns0:CARD_PRODUCTS/ns0:CARD_PRODUCTS_ROW">
                     <tns:CardProduct>
                        <tns:id>
                           <xsl:value-of select="ns0:ID"/>
                        </tns:id>
                        <tns:finInstId>
                           <xsl:value-of select="ns0:F_I"/>
                        </tns:finInstId>
                        <tns:name>
                           <xsl:value-of select="ns0:NAME"/>
                        </tns:name>
                        <tns:productCode>
                           <xsl:value-of select="ns0:CODE"/>
                        </tns:productCode>                            
                     </tns:CardProduct>
                  </xsl:for-each>
               </tns:CardProducts>
            </tns:SalaryProduct>
         </xsl:for-each>
      </tns:SalaryProducts>
   </xsl:template>
</xsl:stylesheet>

Похоже, xslt в порядке (на мой взгляд), но он просто не работает. Единственное, что говорит JDeveloper: «Отсутствует требуемый дочерний элемент SalaryProduct внутри элемента tns: SalaryProducts».

Любая помощь будет оценена по достоинству. Помогите пожалуйста мне. Заранее спасибо!


person PaulV    schedule 12.09.2016    source источник
comment
В вашей таблице стилей нет начального тега <xsl:stylesheet>. И ваш ввод не имеет пространств имен, так почему ваша таблица стилей использует префикс?   -  person michael.hor257k    schedule 12.09.2016
comment
У него есть ‹xsl:stylesheet›. Я пропустил это здесь для краткости.   -  person PaulV    schedule 12.09.2016


Ответы (2)


Если вы просто хотите переименовать элементы, самый простой способ - определить шаблон для каждого («старого») элемента, который создает новый элемент с новым именем.

<xsl:template match="oldname">
  <xsl:element name="newname">
      <xsl:apply-templates />
  </xsl:element>
</xsl:template>

Дополнительно вам нужен шаблон для всего остального: текста, атрибутов (если они есть...)

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

Это может выглядеть примерно так:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="ROWSET">
      <xsl:element name="SalaryProducts">
          <xsl:apply-templates />
      </xsl:element>
    </xsl:template>

    <xsl:template match="ROW">
      <xsl:element name="SalaryProduct">
          <xsl:apply-templates />
      </xsl:element>
    </xsl:template>

    <!-- ... all other element "mappings" -->

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

(Вы можете попробовать это здесь: http://xsltransform.net/bFWR5DS)

В ваших примерах вы используете некоторые пространства имен. Я рекомендую вам узнать о них больше. Но в этом случае я не могу найти никаких причин для использования какого-либо пространства имен, и я думаю, что вы используете их в своем xsl не по назначению.

person Josef Reichardt    schedule 13.09.2016

Спасибо, ребята, за помощь. Проблема решена. Действительно, проблема была в пространстве имен 'ns0:' в выражениях xsl. Итак, есть 2 пути решения проблемы:

  1. Удалите «ns0:» в xsl.
  2. Назначьте пространство имен каждому элементу xml с помощью элемента OSB «Переименовать» (выражение XPath .//*), как в этой статье: http://yuanmengblog.blogspot.com/2011/08/replace-rename-namespace-in-osb.html. Это сложнее, но может быть полезно по некоторым причинам.
person PaulV    schedule 13.09.2016