Преобразование одного формата XML в другой формат XML с использованием XSL - PullRequest
2 голосов
/ 29 апреля 2011

У меня есть код с выводом XML как

<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<products>
    <product>
        <name>abc</name>
        <id>1</id>
    </product>
    <product>
        <name>klm</name>
        <id>2</id>
    </product>
</products>

Я хочу, чтобы тот же XML отображался также в следующем формате:

<?xml version="1.0" encoding="windows-1252" standalone="yes"?>
<products>
    <product>
        <name>
            <value>abc</value>
            <unit></unit>
        </name>
        <id>
            <value>1</value>
            <unit></unit>
        </id>
        <product>
        <name>
            <value>klm</value>
            <unit></unit>
        </name>
        <id>
            <value>2</value>
            <unit></unit>
        </id>
</product>

Как я могу сделать это с помощью XSLT?

Я использую среду Spring. Теги XML для продукта являются переменными. Они варьируются в зависимости от вида продукции. Код для генерации XML:

JAXBContext jc;
try {
   jc = JAXBContext.newInstance(cla);
   Marshaller m;
   m = jc.createMarshaller();
   m.marshal(obj, out); 
} catch (JAXBException e) {
   e.printStackTrace();
}

Edit: Товар может иметь весовую характеристику, поэтому также будет тег

<weight>10lbs<weight>

Эта магия взломает

<weight>
    <value>10</value>
    <unit>lbs</unit>
</weight> 

Ответы [ 2 ]

0 голосов
/ 29 апреля 2011

Вот образец таблицы стилей [отредактирован, чтобы отразить новое требование с элементом веса]:

<xsl:stylesheet
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 version="1.0">

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

 <xsl:template match="products">
   <xsl:copy>
     <product>
       <xsl:apply-templates select="product/*"/>
     </product>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/*">
   <xsl:copy>
     <value>
       <xsl:value-of select="."/>
     </value>
     <unit></unit>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/weight" priority="3">
   <xsl:copy>
     <value>
       <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
     </value>
     <unit>
       <xsl:value-of select="translate(., '0123456789', '')"/>
     </unit>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

Когда я применяю это к вводу образца

<products>
    <product>
        <name>abc</name>
        <id>1</id>
    </product>
    <product>
        <name>klm</name>
        <id>2</id>
    </product>
    <product>
        <name>foo</name>
        <id>3</id>
        <weight>10lbs</weight>
     </product>
</products>

Я получаю

<products>
   <product>
      <name>
         <value>abc</value>
         <unit/>
      </name>
      <id>
         <value>1</value>
         <unit/>
      </id>
      <name>
         <value>klm</value>
         <unit/>
      </name>
      <id>
         <value>2</value>
         <unit/>
      </id>
      <name>
         <value>foo</value>
         <unit/>
      </name>
      <id>
         <value>3</value>
         <unit/>
      </id>
      <weight>
         <value>10</value>
         <unit>lbs</unit>
      </weight>
   </product>
</products>

Исходя из комментария Алехандро, я мог неправильно прочитать желаемый результат, и вы не хотите объединять продукты, в этом случае используйте

<xsl:stylesheet
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 version="1.0">

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

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

 <xsl:template match="product/*">
   <xsl:copy>
     <value>
       <xsl:value-of select="."/>
     </value>
     <unit></unit>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="product/weight" priority="3">
   <xsl:copy>
     <value>
       <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', '')"/>
     </value>
     <unit>
       <xsl:value-of select="translate(., '0123456789', '')"/>
     </unit>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

, тогда вы получите

<products>
   <product>
      <name>
         <value>abc</value>
         <unit/>
      </name>
      <id>
         <value>1</value>
         <unit/>
      </id>
   </product>
   <product>
      <name>
         <value>klm</value>
         <unit/>
      </name>
      <id>
         <value>2</value>
         <unit/>
      </id>
   </product>
   <product>
      <name>
         <value>foo</value>
         <unit/>
      </name>
      <id>
         <value>3</value>
         <unit/>
      </id>
      <weight>
         <value>10</value>
         <unit>lbs</unit>
      </weight>
   </product>
</products>
0 голосов
/ 29 апреля 2011
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="/products">
  <xsl:for-each select="product">
   <xsl:element name="product">
     <xsl:element name="name">
       <xsl:element name="value"><xsl:value-of select="name"/></xsl:element>
       <xsl:element name="unit"/>
     </xsl:element>
     <xsl:element name="id">
       <xsl:element name="value"><xsl:value-of select="id"/></xsl:element>
       <xsl:element name="unit"/>
      </xsl:element>
   </xsl:element>
  </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...