2009-11-18 18 views
6

Şimdi bir süredir bununla mücadele ediyorum ve buna henüz net bir yanıt bulamadık.XSD doğrulanmış XML'i XSLT kullanarak nasıl görüntülersiniz?

Doğru anladığım için, verileri bir XML dosyasına kaydedebilir, bir XSD kullanarak doğrulayabilir ve ardından verileri bir XSLT kullanarak düzgün bir şekilde görüntüleyebilirim.

Ancak XSLT'de görüntülemek istediğim verileri seçmek için XPath sorguları yapmaya çalışan sorunlar yaşıyorum. './/' veya '*' gibi jenerik seçiciler kullandığımda beklediğim sonuçları alırım. Ancak, 'root/responses' veya onun diğer herhangi bir varyantı gibi daha spesifik seçicileri kullanmaya çalıştığımda hiçbir sonuç alamıyorum.

XML dosyası XSD tarafından doğru şekilde doğrulanıyor, bu yüzden verilerimin en azından biraz doğru olduğunu tahmin ediyorum. XML dosyasındaki XSD referansını kaldırdığımda, veri doğrulamasını etkin bir şekilde kaldırarak XPath sorgularım aniden işe yarar! Kaybettiğim bir şey mi var? XSLT'ye ad alanı başvurusu eklemeyi denedim, ancak boşuna.

Aşağıdaki XSD, Örnek XL ve Örnek XSLT'yi tanımladım. Herhangi bir yardım veya ipucu takdir edilecektir! Yapıyı tanımlayan XSD aşağıdaki gibidir. Bu XSD, üç unsuru barındıran ve bir kısıtlama uygulayan basit bir belgeyi tanımlar; responses 'kodu kodu benzersiz olmalıdır.

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="responsecode.xsl"?> 
<root xmlns="http://foo.bar/responsecode.xsd" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://foo.bar/responsecode.xsd responsecode.xsd"> 
    <responses> 
     <response code="firstCode"> 
      <description>Explanation of first code</description> 
     </response> 
     <response code="secondCode"> 
      <description>Explanation of second code</description> 
     </response> 
     <response code="thirdCode"> 
      <description>Explanation of third code.</description> 
     </response> 
    </responses> 
</root> 

Test XSLT belge şöyle XML dosyasıdır belirtilen şu şekildedir:

<?xml version="1.0" encoding="utf-8"?> 
    <xs:schema id="uitext" 
     targetNamespace="http://foo.bar/responsecode.xsd" 
     elementFormDefault="qualified" 
     xmlns:responsecodes="http://foo.bar/responsecode.xsd" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

     <xs:element name="root" type="responsecodes:rootType"> 
      <xs:key name="responseCode"> 
       <xs:selector xpath="responsecodes:responses/responsecodes:response"> 
        <xs:annotation> 
         <xs:documentation>All defined responsecodes</xs:documentation> 
        </xs:annotation> 
       </xs:selector> 
       <xs:field xpath="@code"> 
        <xs:annotation> 
         <xs:documentation>Unique responsecode</xs:documentation> 
        </xs:annotation> 
       </xs:field> 
      </xs:key> 
     </xs:element> 

     <xs:complexType name="rootType"> 
      <xs:sequence> 
       <xs:element name="responses" minOccurs="1" maxOccurs="1" type="responsecodes:responseList"> 
        <xs:annotation> 
         <xs:documentation>Defined responsecodes</xs:documentation> 
        </xs:annotation> 
       </xs:element> 
      </xs:sequence> 
     </xs:complexType> 

     <xs:complexType name="responseList"> 
      <xs:sequence> 
       <xs:element name="response" minOccurs="0" maxOccurs="unbounded" type="responsecodes:response"/> 
      </xs:sequence> 
     </xs:complexType> 

     <xs:complexType name="response"> 
      <xs:sequence> 
       <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"> 
        <xs:annotation> 
         <xs:documentation> 
          Explains the use of the responsecode. 
         </xs:documentation> 
        </xs:annotation> 
       </xs:element> 
      </xs:sequence> 
      <xs:attribute name="code" type="xs:string" use="required"> 
       <xs:annotation> 
        <xs:documentation>Unique code representing the response provided.</xs:documentation> 
       </xs:annotation> 
      </xs:attribute> 
     </xs:complexType> 
    </xs:schema> 

bir örnek XML belgesi olabilir.

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <html><body><h2>Responses</h2> 

       <xsl:for-each select="root/responses/response"> 
        <xsl:choose> 
         <xsl:when test="description != ''"> 
          <br/>'''&lt;description&gt; 
          <br/>'''<xsl:value-of select="description" /> 
          <br/>'''&lt;/description&gt; 
         </xsl:when> 
        </xsl:choose> 
        <br/> 
        <xsl:value-of select="@code" /> 

       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

cevap

6

Ve tabii bir soru gönderebilir olan en kısa sürede, bir cevap kendiniz bulmak (Bu da bir kenara VS2008 numaralandırma tanımlarını benzeyecektir bir biçimde belirtildiği gibi kodlarını görüntülemek fakat olurdu)!

İsim alanı başvurusunda bir yazım hatası olmuş olmalı. çift ​​Bu yayını kontrol ettikten sonra: temelde çıkıyor

xslt-transform-xml-with-namespaces

aynı soru olmak. (Dürüst göndermeden önce aradım ....), tekrar bir isim alanı referansı eklemeyi denedim ve bu sefer kusursuz çalıştı!

Ad alanını 'nsm' (NameSpaceMapping) ve voilá önekiyle eşleştirdim!

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nsm="http://foo.bar/responsecode.xsd"> 
    <xsl:template match="/"> 
     <html><body><h2>Responses</h2> 

         <xsl:for-each select="nsm:root/nsm:responses/nsm:response"> 
           <xsl:choose> 
             <xsl:when test="nsm:description != ''"> 
               <br/>'''&lt;description&gt; 
               <br/>'''<xsl:value-of select="nsm:description" /> 
               <br/>'''&lt;/description&gt; 
             </xsl:when> 
           </xsl:choose> 
           <br/> 
           <xsl:value-of select="@code" /> 

         </xsl:for-each> 
       </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 
+1

Haha! Kendi cevabınla beni birkaç saniye yendin. Güzel gidiyor! – Welbog

+2

Cevabını kendi başınıza bulmakta iyi iş çıkardın. +1 – Welbog

4

Bu bir ad alanı sorunudur. http://foo.bar/responsecode.xsd için bir ad alanı bildirimi eklemeniz ve bu ad alanını kullanan öğelere başvurmanız gerekir. More info can be found here.

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:test="http://foo.bar/responsecode.xsd"> 
    <xsl:template match="/"> 
    <html> 
     <body> 
     <h2>Responses</h2> 

     <xsl:for-each select="test:root/test:responses/test:response"> 
      <xsl:choose> 
      <xsl:when test="test:description != ''"> 
       <br/>'''&lt;description&gt; 
       <br/>'''<xsl:value-of select="test:description" /> 
       <br/>'''&lt;/description&gt; 
      </xsl:when> 
      </xsl:choose> 
      <br/> 
      <xsl:value-of select="@code" /> 

     </xsl:for-each> 
     </body> 
    </html> 
    </xsl:template> 
</xsl:stylesheet> 

Not: xsl:stylesheet 'ın özelliklerinde "xmlns: Test"

Yani temelde böyle bir şey gerekir. Bunu bir test yaptım ve işe yarıyor.

8

Basit sorun: XML öğeleriniz XSLT'nizin hiçbir şey bilmediği bir ad alanında.

<root xmlns="http://foo.bar/responsecode.xsd"> 
    <responses> 
    <!-- ... --> 
    </responses> 
</root> 

"http://foo.bar/responsecode.xsd" ad içine <root> ve tüm alt öğeleri koyar.

bu gibi XSL'yi değiştirin

: namespace ilan ve bir önek verilir nasıl

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:foo="http://foo.bar/responsecode.xsd" 
    exclude-result-prefixes="foo" 
> 
    <xsl:template match="/"> 
    <html> 
     <body> 
     <h2>Responses</h2> 
     <xsl:for-each select="foo:root/foo:responses/foo:response"> 
      <!-- ... --> 
     </xsl:for-each> 
     </body> 
    </html> 
    </xsl:template> 
</xsl:stylesheet> 

Not. Daha sonra, bu ad alanındaki tüm düğümler bu önek kullanılarak adlandırılır. exclude-result-prefixes, isim alanının gereksiz çıktıda görünmediğinden emin olmak için kullanılır.

+0

Ah iyi. Daha hızlı yazmayı öğrenmeliyim. :) – Tomalak

+0

Siz de! Herkes bunu aynı anda alıyor ... – Welbog

+0

+1 yine de, exclude-sonuç-önekleri için. – Welbog