2008-11-12 15 views
12

Mam dokument XML coś podobnego :::Jak "wybrać" z XML z przestrzeniami nazw?

<?xml version="1.0" encoding="utf-8"?> 
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
      xmlns:o="urn:schemas-microsoft-com:office:office" 
      xmlns:x="urn:schemas-microsoft-com:office:excel" 
      xmlns="urn:schemas-microsoft-com:office:spreadsheet"> 
    <Worksheet ss:Name="Worksheet1"> 
    <Table> 
     <Column ss:Width="100"></Column> 

     <Row> 
     <Cell ss:Index="1" ss:StyleID="headerStyle"> 
      <Data ss:Type="String">Submitted By</Data> 
     </Cell> 
     </Row> 
     <Row> 
     <Cell ss:Index="1" ss:StyleID="alternatingItemStyle"> 
      <Data ss:Type="String">Value1-0</Data> 
     </Cell> 
     </Row> 
    </Table> 
    <AutoFilter xmlns="urn:schemas-microsoft-com:office:excel" 
       x:Range="R1C1:R1C5"></AutoFilter> 
    </Worksheet> 
</Workbook> 

Problem jest, gdy próbuje wybrać wiersze z

<xsl:for-each select="//Row"> 
    <xsl:copy-of select="."/> 
    </xsl:for-each> 

To nie jest dopasowanie. Usunąłem wszystkie odstępy między nazwami i wszystko działa dobrze. Jak więc uzyskać "wybierz", aby dopasować wiersz?

Odpowiedz

28

stwierdzenie prefiks obszaru nazw dla przestrzeni nazw w Twoim XSLT, a następnie przy użyciu tego select prefiks:

<xsl:stylesheet ... xmlns:os="urn:schemas-microsoft-com:office:spreadsheet"> 
    ... 
    <xsl:for-each select="//os:Row"> 
    ... 
    </xsl:for-each> 
    ... 
</xsl:stylesheet> 

To zwykle skutkuje XPaths, które są łatwe do odczytania. Jednak narzędzia XSLT/XPath generują następujące, co odpowiada kod:

<xsl:for-each select="//*[local-name()='Row' = and namespace-uri()='urn:schemas-microsoft-com:office:spreadsheet']"> 
    ... 
</xsl:for-each> 
+2

Ten ostatni wydaje się być bardziej zwięzły. Dzięki. –

10

Jeśli nie dbają o nazw, można użyć `local-name XPath()” funkcja:

<xsl:for-each select="//*[local-name() = 'Row']"> 
    <xsl:copy-of select="."/> 
</xsl:for-each> 

Alternatywnie takie same samo można wyrazić w ten sposób. Nie jestem pewien, czy jest to standardowa ścieżka XPath i czy obsługują ją wszystkie implementacje XPath (ColdFusion, więc prawdopodobnie Java też robi). Może ktoś wie, czy to jest zgodne z jakimkolwiek standardem.

<xsl:for-each select="//:Row"> 
    <xsl:copy-of select="."/> 
</xsl:for-each> 
+1

Ten test QName '*: nazwa lokalna' jest ważny tylko w XSLT/XPath 2.0 –

+0

To rozwiązanie jest trochę brudne, ale skuteczne. Rozwiązał również mój problem (próby wybrania śliskiego węzła podrzędnego z nazwami). –

+0

@Kevin Która jego część? Pierwszy czy drugi? – Tomalak

7

Tomalek i ckarras dać dobre odpowiedzi, ale chcę wyjaśnić przyczyny nimi.

elementy, które nie są dopasowane są w domyślnej przestrzeni nazw w zakresie, w jakim występują one w dokumencie, to znaczy, że są w przestrzeni nazw zadeklarowanych w tym zakresie bez prefiksu (np

xmlns="urn:schemas-microsoft-com:office:spreadsheet" 

na elemencie Workbook). Mimo że zmiennym brakuje prefiksu przestrzeni nazw, są one w przestrzeni nazw.

Jednak XPath wymaga, aby wszystkie nazwy elementów w przestrzeni nazw były kwalifikowane za pomocą przedrostka lub aby przestrzeń nazw była jawnie określona w namespace-uri() w predykacie. Dlatego musisz użyć funkcji local-name() w predykacie, aby dopasować nazwę elementu (i użyć funkcji namespace-uri(), jeśli istnieje niebezpieczeństwo kolizji nazw między obszarami nazw) lub musisz zadeklarować każdą przestrzeń nazw, w której chcesz dopasować elementy w XPath z prefiksem i kwalifikuj nazwy elementów z przedrostkami przestrzeni nazw w wyrażeniach XPath.

Powiązane problemy