2016-08-06 3 views
0

У меня есть XML, как это,Вызов шаблон XSLT рекурсии с ключом матча

<categories> 
    <data> 
     <category_id>216</category_id> 
     <children_sort_order>217</children_sort_order> 
     <children_sort_order>324</children_sort_order> 
     <children_sort_order>395</children_sort_order> 
     <children_sort_order>580</children_sort_order> 
     <children_sort_order>506</children_sort_order> 
     <children_sort_order>466</children_sort_order> 
     <children_sort_order>626</children_sort_order> 
     <children_sort_order>532</children_sort_order> 
     <depth>0</depth> 
     <description/> 
     <name>Products</name> 
     <path>products</path> 
     <slug>products</slug> 
     <state>live</state> 
     <status> 
      <state>live</state> 
     </status> 
     <updated_at>2016-06-09T05:13:08Z</updated_at> 
     <westfield_locale>en_AU</westfield_locale> 
     <sort_order>0</sort_order> 
    </data> 
    <data> 
     <category_id>217</category_id> 
     <children_sort_order>218</children_sort_order> 
     <children_sort_order>319</children_sort_order> 
     <children_sort_order>232</children_sort_order> 
     <children_sort_order>237</children_sort_order> 
     <children_sort_order>244</children_sort_order> 
     <children_sort_order>255</children_sort_order> 
     <children_sort_order>225</children_sort_order> 
     <children_sort_order>307</children_sort_order> 
     <children_sort_order>286</children_sort_order> 
     <children_sort_order>262</children_sort_order> 
     <children_sort_order>269</children_sort_order> 
     <children_sort_order>279</children_sort_order> 
     <children_sort_order>251</children_sort_order> 
     <children_sort_order>299</children_sort_order> 
     <children_sort_order>292</children_sort_order> 
     <depth>1</depth> 
     <description/> 
    <name>Women's</name> 
     <path>products/womens-fashion-accessories</path> 
     <slug>womens-fashion-accessories</slug> 
     <state>live</state> 
     <status> 
      <state>live</state> 
     </status> 
     <updated_at>2016-07-12T03:35:17Z</updated_at> 
     <westfield_locale>en_AU</westfield_locale> 
     <sort_order>0</sort_order> 
    </data> 
    <errors /> 
    <meta> 
     <api_version>1.3</api_version> 
     <deprecation_information /> 
    </meta> 
</categories> 

Я хочу, чтобы прочитать верхний элемент и создать родительский XML-элемент, а затем прочитать соответствующую категорию и вставить в качестве ребенка к первому элементу , Таким образом, выход должен быть таким:

<Category category_id="216" name="Products" parent="0"> 
    <Category category_id="217" name="Women's" parent="216"> 
    </Category> 
</Category> 

Я попытался применить рекурсивный шаблон с сочетанием клавиш, но это не сработало.

<xsl:key name="children-search" match="data" use="category_id"/> 
    <xsl:template name="Category"> 
      <xsl:param name="parent"/> 

      <xsl:variable name="current" select="category_id"/> 

      <xsl:element name="Category"> 
       <xsl:attribute name="id"><xsl:value-of select="category_id"/></xsl:attribute> 
       <xsl:attribute name="code">1</xsl:attribute><!--<xsl:value-of select="sort_order"/></xsl:attribute>--><!-- Field is no longer provided in the Westfield Category Data --> 
       <xsl:attribute name="name"><xsl:value-of select="slug"/></xsl:attribute> 
       <xsl:attribute name="displayname"><xsl:value-of select="name"/></xsl:attribute> 
       <xsl:attribute name="desc"><xsl:value-of select="description"/></xsl:attribute> 
       <xsl:attribute name="ismappable">1</xsl:attribute> <!-- Field is no longer provided in the Westfield Category Data --> 
       <xsl:attribute name="order"><xsl:value-of select="sort_order"/></xsl:attribute> 
       <xsl:attribute name="active"><xsl:choose><xsl:when test="state = 'live'">1</xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose></xsl:attribute> 
       <xsl:attribute name="parent"><xsl:value-of select="$parent"/></xsl:attribute> 
      </xsl:element> 

      <!-- recursive call --> 
      <xsl:for-each select="children_sort_order"> 
       <xsl:call-template name="Category"><xsl:with-param name="parent" select="key('children-search', $current)"/></xsl:call-template> 
      </xsl:for-each> 
     </xsl:template> 

Пожалуйста, дайте мне знать, если есть лучший способ приблизиться к этому. Большое спасибо

ответ

1

Вам не нужны именованные шаблоны с параметрами здесь. Вместо этого, если у вас есть шаблон, который соответствовал data, вы могли бы получить дочерние элементы, как так: (! Спасибо Martin Honnen)

<xsl:for-each select="children_sort_ordesr"> 
    <xsl:apply-templates select="key('children-search', .)" /> 
</xsl:for-each> 

Или еще лучше это ..

<xsl:apply-templates select="key('children-search', children_sort_order)" /> 

Попробуйте это XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:key name="children-search" match="data" use="category_id"/> 
<xsl:key name="parent_search" match="children_sort_order" use="."/> 

<xsl:template match="categories"> 
    <xsl:copy> 
     <xsl:apply-templates select="data[not(key('parent_search', category_id))]" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="data"> 
    <Category id="{category_id}" name="{name}"> 
     <!-- recursive call --> 
     <xsl:apply-templates select="key('children-search', children_sort_order)" /> 
    </Category> 
    </xsl:template> 
</xsl:stylesheet> 

Обратите внимание на использование ключа «parent_search», который просто используется, чтобы выбрать элемент верхнего уровня data (т.е. data элемент ш у которого нет родителя). Вы могли бы упростить его до <xsl:apply-templates select="data[1]" />, если элемент верхнего уровня data всегда был первым элементом data в XML.

Также обратите внимание на использование Attribute Value Templates для создания атрибутов на элементе Category, что значительно упрощает XSLT.

+0

Зачем вам нужно, чтобы 'apply-templates' вставлялись в' for-each', почему бы вам просто не использовать ' '? –

+0

@MartinHonnen Я бы ожидал, что это применит шаблоны только к первому узлу в XSLT 1.0. – Tomalak

+2

@Tomalak, https://www.w3.org/TR/xslt#function-key говорит: «Когда второй аргумент ключевой функции имеет тип node-set, то результатом является объединение результата применения ключевую функцию для строкового значения каждого из узлов в наборе узлов аргументов. " поэтому я не вижу ограничения XSLT 1.0 на один аргумент узла. –

Смежные вопросы