2010-10-20 2 views
1

Я узнал о XSLT и XPath в w3schools, но это не совсем то, что я хотел. Есть только примеры преобразования XSLT 2 HTML, это довольно просто, но мне нужно преобразование XML 2 XML и не может найти хороший учебник с примерами ... Я загрузил MSXSL.exe, но не могу найти примеры использования его для преобразования XML ... Может ли кто-нибудь написать образец? У меня есть customers.xml нравится:XML 2 XML с использованием XSLT

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<!--Customers table from Northwind database--> 
<Customers> 
    <Customer CustomerID="ALFKI"> 
    <CompanyName>Alfreds Futterkiste</CompanyName> 
    <Country>Germany</Country> 
    <Orders> 
     <Order OrderID="10643"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10692"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10702"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10835"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="10952"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
     <Order OrderID="11011"> 
     <ShipCity>Berlin</ShipCity> 
     </Order> 
    </Orders> 
    </Customer> 
    <Customer CustomerID="ANATR"> 
    <CompanyName>Ana Trujillo Emparedados y helados</CompanyName> 
    <Country>Mexico</Country> 
    <Orders> 
     <Order OrderID="10308"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10625"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10759"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
     <Order OrderID="10926"> 
     <ShipCity>México D.F.</ShipCity> 
     </Order> 
    </Orders> 
    </Customer> 
</Customers> 

И пытается создать другой XML, содержащий только «страна» узлы .. Как написать это?

+0

Хороший вопрос, +1. См. Мой ответ для двух решений. :) –

ответ

1

Вот два различных решения: простой один и более сложный, который производит только уникальные страны:

.1. Получить все Country элементы:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="*[not(self::Country)]"> 
    <xsl:apply-templates select="*"/> 
</xsl:template> 
</xsl:stylesheet> 

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

<Country>Germany</Country> 
<Country>Mexico</Country> 

.2. Найти все уникальные страны:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:key name="kCountryByVal" match="Country" use="."/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
     "/*/*/Country[generate-id() 
        = 
        generate-id(key('kCountryByVal',.)[1]) 
        ] 
     "/> 
</xsl:template> 
</xsl:stylesheet> 

когда это преобразование применяется на любой документ XML со структурой предоставленного документа, в котором некоторые Country элементы могут иметь такое же значение, только один Country элемент для каждого значения является произведено.

С прилагаемого документа XML мы до сих пор получить тот же результат:

<Country>Germany</Country> 
<Country>Mexico</Country> 
3

Это точно так же, вам просто нужно использовать атрибут method элемента output соответственно.

+1

+1, примеры здесь: http://www.w3schools.com/xsl/el_output.asp – Bruno

3

Что-то, как это должно работать ...

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
    <Countries> 
     <xsl:apply-templates select="//Country" mode="copyNode" /> 
    </Countries> 
    </xsl:template> 

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

... Вот результат ...

<?xml version="1.0" encoding="utf-8"?> 
<Countries> 
    <Country>Germany</Country> 
    <Country>Mexico</Country> 
</Countries> 
+0

Уверен, что мне не нужно пространство имен Microsoft, если я его не использую. –

+0

Я должен добавить, что это будет включать в себя все дочерние узлы элементов '', если они существуют. –

1

Его довольно просто, нужно просто написать XML вместо HTML внутри ваших xslt шаблонов.

Следующая (непроверенные) следует, чтобы вы начали:

<xsl:template match="/"> 
    <Countries> 
    <xsl:apply-templates select="Customers/Customer" /> 
    </Countries> 
</xsl:template> 

<xsl:template match="Customer"> 
    <Country> 
    <xsl:value-of select="Country" /> 
    </Country> 
</xsl:template> 

Кроме того, для процессора XSLT Я от всей души рекомендую Visual Studio - имеет отличную XSLT отладчик, который будет помогать вам не будет конца в понимании таблицы стилей , (Я не уверен, если эта функция включена в экспресс-изданиях ...)

0

В тяговой стиле, то это должно быть короче стилей выражения этой трансформации:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="text()"/> 
    <xsl:template match="@*|/*|Country|Country/text()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<Customers> 
    <Country>Germany</Country> 
    <Country>Mexico</Country> 
</Customers>