2009-12-04 15 views
12

başka bir XML dokümana bir XML doc dönüşümü, ama hiçbiri tam olarak çözmeye çalışıyorum cevaplamak ve belki ben m sadece çok yoğun ben yapmaya çalışıyorum ne diğer cevaplar birini nasıl uygulanacağını görmek için. xmlns = "" ortadan kaldırmak için nasıl XSLT tarafından üretilen girdileri Tamam, bu soru üzerine sayısız varyasyonları gördüğüm

<?xml version="1.0" encoding="utf-8"?> 
<message> 
    <cmd id="api_info"> 
    <api-version>1.0</api-version> 
    <api-build>1.0.0.0</api-build> 
    </cmd> 
</message> 

Şimdi bir XSLT bu XML uygulayarak ediyorum dönüşümü vardır:

aşağıdaki gibi görünür bazı XML var. XSLT aşağıdaki benzer: Ben olsun çıktı ben istediğim temelde

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fo="http://www.w3.org/1999/XSL/Format" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       version="2.0"> 

    <xsl:output method="xml" version="1.0" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="message"/> 
    </xsl:template> 

    <xsl:template match="message"> 
     <xsl:element name="message" xmlns="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="/message/cmd/@id"> 
     <xsl:variable name="_commandType" select="/message/cmd/@id"/> 
     <xsl:element name="messageHeader"> 
      <xsl:element name="cmdType"> 
       <xsl:value-of select="$_commandType"/> 
      </xsl:element> 
     </xsl:element> 

     <xsl:element name="messageBody"> 
      <xsl:choose> 
       <xsl:when test="$_commandType = 'api_info'"> 
        <xsl:element name="apiInfoBody"> 
         <xsl:element name="apiVersion"> 
          <xsl:value-of select="/message/cmd/api-version"/> 
         </xsl:element> 
         <xsl:element name="apiBuild"> 
          <xsl:value-of select="/message/cmd/api-build"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
       <xsl:when test="$_commandType = 'communicationError'"> 
        <xsl:element name="communicationErrorBody"> 
         <xsl:element name="errorCode"> 
          <xsl:value-of select="error-code"/> 
         </xsl:element> 
         <xsl:element name="badCmd"> 
          <xsl:value-of select="bad-cmd"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

ve benzeri şekilde aşağıdaki:

<?xml version="1.0" encoding="UTF-8"?> 
<message xmlns="http://www.companyname.com/schemas/product/Version001"> 
    <messageHeader xmlns=""> 
     <cmdType>api_info</cmdType> 
    </messageHeader> 
    <messageBody xmlns=""> 
     <apiInfoBody> 
      <apiVersion>1.0</apiVersion> 
      <apiBuild>1.0.0.0</apiBuild> 
     </apiInfoBody> 
    </messageBody> 
</message> 

Ama benim istemiyorum xmlns vardır =" "<messageHeader>" ve iletisindeki " öznitelikleri" 0B öğeleri.

Şimdi ben açıkça bu elemanlar için XSLT'de ad belirtirseniz, daha sonra istenmeyen özellik bu özellikleri çocuklarına bir seviye aşağı itti alır olduğunu tespit ettik.

Sadece benim xsl her birine niteliği xmlns = "" http://www.companyname.com/schemas/product/Version001 "eklemek açıkça benim tüm XSLT geçmesi ve olabilir

. Eleman tanımları, ama daha zarif bir şekilde olması gerektiğini biliyoruz Biz programcılar saçmalık bu tür bir kısayol yok için çok tembel. benim XSLT kısaltılmış örnek gibi basit bir ibaret olmasaydı, öyle de yapmak için cazip. Ama daha iyi bir yolu olmalı biliyorum.

herkes burada özlüyorum biliyor mu?

sayesinde

AlarmTripper

cevap

8

Kullanım dışlamak-sonuç-önekleri xsl: öneki "#default"

bunun için W3C referans HERE

DÜZENLEME olduğu ile stil etiketi: Tamam, olması gereken XSL'nizi daha dikkatli bir şekilde inceledi. Mesaj etiketindeki xmlns'i stil sayfası etiketine taşıyın. Bu, aynı ad alanında TÜM sonucu öğelerinin koymak ve mesaj etiketi üzerinde bir ad alanı niteliği ile sonuçlanacaktır. Bunu Oksijen/XML'de çalıştırdım ve istediğiniz çıktıyı aldım. Tamam

+0

XML çıkışını değiştirmediniz. – AlarmTripper

+0

Hangi XSLT işlemci kullanıyorsunuz? –

+0

Evet, yeni önerinizin de işe yaradığını doğruladım ve muhtemelen xmlns ödevini stil sayfası öğesinde tuttuğu için benimkinden daha iyi bir çözüm olduğunu doğruladım. Ve #default seçeneği, diğer ad alanı öneklerinin her birini hariç tutmamı engelliyor. Çok teşekkürler. Bu XSLT ile ilgili bir şeyler öğrenmem gereken çok şey var ve bence isim alanları belki de daha zorlu yönlerden. – AlarmTripper

0

, ben bunu anladım.

istediğim XSLT şuna benzer:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:fo="http://www.w3.org/1999/XSL/Format" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:fn="http://www.w3.org/2005/xpath-functions" 
       exclude-result-prefixes="xsl fo xs fn"> 

    <xsl:output method="xml" version="1.0" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="message"/> 
    </xsl:template> 

    <xsl:template match="message"> 
     <message namespace="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </message> 
    </xsl:template> 

    <xsl:template match="/message/cmd/@id"> 
     <xsl:variable name="_commandType" select="/message/cmd/@id"/> 

     <xsl:element name="messageHeader"> 
      <xsl:element name="cmdType"> 
       <xsl:value-of select="$_commandType"/> 
      </xsl:element> 
     </xsl:element> 

     <xsl:element name="messageBody"> 
      <xsl:choose> 
       <xsl:when test="$_commandType = 'api_info'"> 
        <xsl:element name="apiInfoBody"> 
         <xsl:element name="apiVersion"> 
          <xsl:value-of select="/message/cmd/api-version"/> 
         </xsl:element> 
         <xsl:element name="apiBuild"> 
          <xsl:value-of select="/message/cmd/api-build"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
       <xsl:when test="$_commandType = 'communicationError'"> 
        <xsl:element name="communicationErrorBody"> 
         <xsl:element name="errorCode"> 
          <xsl:value-of select="error-code"/> 
         </xsl:element> 
         <xsl:element name="badCmd"> 
          <xsl:value-of select="bad-cmd"/> 
         </xsl:element> 
        </xsl:element> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

o dışlamak-sonuç-önekleri eklemek için niteliğini < xsl oldu sabit değişimi: stil > elemanı ve bölüm değiştirme oldu:

:

<xsl:template match="message"> 
     <xsl:element name="message" xmlns="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </xsl:element> 
    </xsl:template> 

yerine aşağıdaki olmaya

<xsl:template match="message"> 
     <message namespace="http://www.companyname.com/schemas/product/Version001"> 
      <xsl:apply-templates select="/message/cmd/@id"/> 
     </message> 
    </xsl:template> 

Şimdi tekrar mutlu oluyorum.

Bunu yapmak için muhtemelen daha iyi yollar vardır, ancak bu benim için çalışıyor. Gelecek önerileriniz hala kabul edilir.

0

Jim Garrison'un (güncellenmiş) yanıtı, ihtiyacınız olan her şeydir. Ancak, gönderdiğiniz güncellenmiş stil sayfası sonuçta bir "isim-alanı" niteliği çıkarır, bu yüzden sizin için neyin iyi olduğundan emin değilim.

Anlamak gereken en önemli şey, varsayılan ad alanının nasıl çalıştığıdır. Xmlns'i sonuca çıkarabileceğiniz bir özellik olarak düşünmeyin. Bunun yerine, stil sayfanızın sözdizimsel bir ayrıntısı olarak düşünün. Buradaki amaç, onun altındaki her şey için varsayılan ad alanını ayarlamaktır (öğenin kendisi ve soyundan gelenlerin her biri geçersiz kılınana kadar). (Sırasıyla, bu, XML'den farklı bir yapıya sahip olan sonuçta aynı işleve sahiptir.)

Stil sayfanızdaki (örneğin, < ileti> gibi) basit sonuç öğeleri ve < xsl: element > talimatlar (ör. < xsl: element name = "message">), sağlanan isim bir önek kullanmıyorsa, her ikisi de varsayılan ad alanını kullanır. Aynı ad alanına sahip olmak için numaralı numaralı telefonu istiyorsanız, Jim Garrison'ın önerdiği gibi, stil sayfanızın en üstünde varsayılan bir ad alanı koymanız gerekecektir.

Aksi takdirde, bu ad alanında bulunmayan bazı öğelerle sonuçlanırsınız. Bu nedenle sonuçta xmlns = "" (bu öğeler için ad boşluğunun gösterilmesi) bulunur.

+0

Teşekkürler Evan! Buraya ulaşabileceğim tüm yardımları takdir ediyorum. 'Xmlns'in bir özellik gibi göründüğünü okudum, ama değil. Geri dönüp kodu değiştirdim, böylece Jim'in bir ad alanı niteleyicisi (terminoloji?) Eklediği gibi önerdi, böylece ad alanı etiketim artık 'stylesheet' tanımımda kaldı ve 'xmlns: grf = "http: //www.blahblah.com "ve sonra benim elemanlarım" grf: "ile önceliğe sahip olduğundan emin olmak için geri döndüm. Şirketim çevresinde hiç kimse XSLT veya XPATH ile fazla bir şey yapmadığından buradaki uzmanların yardımları paha biçilemez. Yine de onu öğrenmekten keyif alıyorum! – AlarmTripper

İlgili konular