2010-09-06 15 views
7

Próbuję przekształcić plik XML o następującej przestrzeni nazw, ale nie mogłem znaleźć sposobu, aby działał z domyślną przestrzenią nazw bez dodawania przedrostka do wyjściowego pliku XML.XSLT przekształcić XML z domyślną przestrzenią nazw bez dodawania prefiksu?

oryginalny plik XML:

<pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass"> 

mogę to zrobić pracę przez dodanie prefiksu do domyślnej przestrzeni nazw (ostatni), ale jak mogłem wyprowadzać XML bez dodawania prefiksu, jest możliwe przez przy użyciu XslCompiledTransform w .NET 4?

+0

Wygląda na to, że możesz * nie * znaleźć sposób, aby działał z domyślną przestrzenią nazw bez dodawania przedrostka do wyjściowego kodu XML. W jaki sposób to nie działa? Jakie obserwowane zachowanie występuje, gdy nie dodajesz prefiksu? Oznaczyłeś to za pomocą XSLT, więc może masz na myśli to, że procesor XSLT nie rozpoznaje elementu pExport w przestrzeni nazw workflow/compass? Potrzebne są więcej informacji. Może to pomóc w wyświetleniu odpowiedniej części arkusza stylów. – LarsH

+0

Dobre pytanie (+1).Zobacz moją odpowiedź na konkretny przykład i zastosowane rozwiązanie. –

+0

LarsH, tak, co miałem na myśli to, że bez dodawania prefiksu, wyjściowy XSLT nie byłby w stanie dopasować węzłów do domyślnej przestrzeni nazw (bez tagu). Szukam sposobu na dopasowanie tych elementów bez dodawania własnego prefiksu dla domyślnego obszaru nazw. –

Odpowiedz

4

mogę zrobić to pracuje dodając prefiks do domyślnej przestrzeni nazw (ostatni ), ale jak mogłem wyprowadzać XML bez dodawania prefiksu, to możliwe dzięki zastosowaniu XslCompiledTransform w. NET 4?

Oto konkretny przykład, jak to zrobić:

tej transformacji:

<xsl:stylesheet version="1.0" 
xmlns="http://workflow.converga.com.au/compass" 
xmlns:c="http://workflow.converga.com.au/compass" 
xmlns:ext="http://exslt.org/common" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
exclude-result-prefixes="c ext xsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pnewItem"> 
    <item name="wine"> 
    <price>3</price> 
    <quantity>5000</quantity> 
    </item> 
</xsl:param> 

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

<xsl:template match="c:item[last()]"> 
    <xsl:call-template name="identity"/> 
    <xsl:copy-of select="ext:node-set($pnewItem)/*"/> 
</xsl:template> 
</xsl:stylesheet> 

gdy stosowane z XslCompiledTransform na poniższym dokumencie XML:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
<Goods> 
    <item name="tobacco"> 
    <price>5</price> 
    <quantity>1000</quantity> 
    </item> 
</Goods> 
</pExport> 

produkuje chciał (ten sam dokument XML z nowej pozycji dodanej), prawidłowy wynik:

<pExport xmlns="http://workflow.converga.com.au/compass"> 
    <Goods> 
    <item name="tobacco"> 
     <price>5</price> 
     <quantity>1000</quantity> 
    </item> 
    <item name="wine"> 
     <price>3</price> 
     <quantity>5000</quantity> 
    </item> 
    </Goods> 
</pExport> 
+0

Dziękuję za przykład, że zadziałało, dodając dodatkową domyślną przestrzeń nazw bez prefiksu i opcji "exclude-result-prefixex". Właściwie to nie w pełni rozumiem twój kod i jak działają (po prostu wczoraj nauczyłem się XSLT). Na przykład, co to jest sekcja w pierwszym bloku kodu? –

+0

Drobna rzecz, w wyjściowym XML domyślna przestrzeń nazw jest zawsze pierwsza, czy mogę to zmienić na ostatnią, która jest pozycją z oryginalnego XML. –

+0

@pstar: Specyfikacje XSLT i XML W3C nie wymagają żadnej określonej kolejności dla atrybutów i węzłów przestrzeni nazw. Ich względna kolejność jest "zależna od implementacji". Oznacza to, że w zależności od konkretnego procesora XSLT, którego używasz, nie masz żadnej kontroli nad porządkowaniem deklaracji przestrzeni nazw, lub jeśli masz jakąś kontrolę, ta "funkcja" nie jest przenośna i nie jest obsługiwana przez inne procesory XSLT. –

1

Po prostu musisz zdefiniować domyślny obszar nazw w XSLT. Jeśli również określić jedną z prefiksem, jak również dzięki czemu można wybrać elementy z XML wejściowego z łatwością:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass"> 
    <xsl:template match="compass:pExport"> 
    <pExport>...</pExport> 
    ... 

Powyższy szablon będzie pasował na elemencie XML wejście - i dosłowne elementem tworzony będzie w domyślnym wyjściowa przestrzeń nazw (która jest tą samą przestrzenią nazw).

Oczywiście należy pamiętać, że w XML prefiks jest nieistotny - dwa elementy są identyczne, jeśli mają tę samą przestrzeń nazw i nazwę lokalną, nawet jeśli dwa prefiksy są zdefiniowane dla tej przestrzeni nazw.

<element xmlns="http://test.com"></element> 
<ns01:element xmlns:ns01="http://test.com"></ns01:element> 

Dwa powyższe elementy są takie same, ponieważ mają taką samą pełną nazwę.

+0

do kopiowania dopasowanego elementu z tą samą przestrzenią nazw, nie musisz zadeklarować domyślnej przestrzeni nazw dla wyjścia, instrukcja 'copy' również działa w ten sposób. –

+0

Myślę, że masz rację w tym sensie, że prefiks nie powinien wpływać na przestrzeń nazw. Twoje rozwiązanie działa w tym sensie. To, czego szukam, to rozwiązanie bez dodawania własnego prefiksu do domyślnej przestrzeni nazw. –

+0

Prefiks nie ma znaczenia * w teorii *. W praktyce niektóre parsery nie są zgodne z obszarami nazw, ale nadal chcesz wygenerować dokument za pomocą zgodnego pisarza. Również specyfikacje niektórych standartów opartych na XML nie używają w ogóle przestrzeni nazw. – dolmen

4

Kluczem jest użycie atrybutu exclude-result-prefixes na elemencie stylesheet.

Istnieje kilka dobrych objaśnień w this section z XSLT FAQ.

+0

Dziękuję Dolce za wskazanie mi informacji. Właściwie to już przeczytałem trochę XSLT, ale go nie znalazłem. Zgadnij, że często zadawane pytania są dla mnie zbyt dużą informacją. –

+0

Dobrym sposobem na podziękowanie za odpowiedź jest głosowanie za kliknięciem strzałki w górę po lewej stronie. Mógłbyś to zrobić dla mnie? – dolmen

+0

Zagłosowano na najczęściej zadawane pytania dotyczące XLT. – Fortisimo

Powiązane problemy