Это моя первая попытка XSLT и первый пост на SO. Мне нужно преобразовать ориентированный на таблицы / строки XML в ориентированный на дерево XML с уникальными ветвями и листьями. Я использую отладку XSLT 1.1 и IE8 в VS2008. Я изучил 2-е издание XSLT (М. Кей) и статью Теннисона в технике группирования мюнхенов, которую я пытался объединить. Я пытался включить элементы, относящиеся к возможным проблемным областям, таким как восстановление родственных связей с другой переменной, чтобы использовать предыдущего родного брата для получения уникальности, но мой предыдущий родной брат всегда равен нулю и см. маршрут 2 или почтовый индекс 23456. Я изучил много сообщений, связанных с предыдущим братом, но не могу получить ожидаемый результат. Извините за длинный пост, но я хотел сделать его как можно более понятным.
Спасибо,
Al
Мой ввод:
<?xml version="1.0"?><root><dataset><CITY_DATA>
<ROW count='1'><CITY>BOSTON</CITY><ZIP>12345</ZIP><ROUTE_NM>Route 1</ROUTE_NM></ROW>
<ROW count='2'><CITY>BOSTON</CITY><ZIP>12345</ZIP><ROUTE_NM>Route 1</ROUTE_NM></ROW>
<ROW count='3'><CITY>BOSTON</CITY><ZIP>34567</ZIP><ROUTE_NM>Route 2</ROUTE_NM></ROW>
<ROW count='4'><CITY>LAKEVILLE</CITY><ZIP>01234</ZIP><ROUTE_NM>Route 1</ROUTE_NM></ROW>
<ROW count='5'><CITY>LAKEVILLE</CITY><ZIP>01234</ZIP><ROUTE_NM>Route 1</ROUTE_NM></ROW>
<ROW count='6'><CITY>LAKEVILLE</CITY><ZIP>23456</ZIP><ROUTE_NM>Route 1</ROUTE_NM></ROW>
</CITY_DATA></dataset></root>
Мой XSL:
<xsl:transform version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:key name="CITY" match="ROW" use="CITY" />
<xsl:template match="CITY_DATA">
<FIRST_BRANCH>
<xsl:for-each select="ROW[count(. | key('CITY', CITY)[1]) = 1]">
<xsl:sort select="CITY" />
<CITY>
<xsl:value-of select="CITY" />
<xsl:variable name="routes-list">
<xsl:for-each select="key('CITY',CITY)">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($routes-list)//ROUTE_NM">
<PRE_ROUTE_NM>
<xsl:value-of select="preceding-sibling::ROUTE_NM"/>
</PRE_ROUTE_NM>
<VAL_ROUTE_NM>
<xsl:value-of select="//ROUTE_NM" />
</VAL_ROUTE_NM>
<xsl:if test="//ROUTE_NM[not(preceding-sibling::ROUTE_NM[1])]">
<ROUTE_NM>
<xsl:value-of select="//ROUTE_NM" />
<xsl:for-each select="msxsl:node-set($routes-list)//ZIP">
<xsl:if test="//ZIP[not(preceding-sibling::ZIP[1])]">
<ZIP>
<xsl:value-of select="//ZIP" />
</ZIP>
</xsl:if>
</xsl:for-each>
</ROUTE_NM>
</xsl:if>
</xsl:for-each>
</CITY>
</xsl:for-each>
</FIRST_BRANCH>
</xsl:template>
</xsl:transform>
Мой плохой вывод:
**** ТЕКУЩИЙ НЕПРАВИЛЬНЫЙ ВЫХОД ******* *********
<?xml version="1.0" encoding="utf-8"?>
<FIRST_BRANCH xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<CITY>BOSTON
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
<ZIP>12345</ZIP>
</ROUTE_NM>
</CITY>
<CITY>LAKEVILLE
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
<ZIP>01234</ZIP>
</ROUTE_NM>
</CITY>
</FIRST_BRANCH>
Мой ожидаемый результат:
*** ниже ожидаемого выхода **** ***************** *
<?xml version="1.0" encoding="utf-8"?>
<FIRST_BRANCH xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<CITY>BOSTON
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>12345</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM>Route 1</PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<PRE_ROUTE_NM>Route 1</PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 2</VAL_ROUTE_NM>
<ROUTE_NM>Route 2
<ZIP>34567</ZIP>
</ROUTE_NM>
</CITY>
<CITY>LAKEVILLE
<PRE_ROUTE_NM></PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<ROUTE_NM>Route 1
<ZIP>01234</ZIP>
<ZIP>23456</ZIP>
</ROUTE_NM>
<PRE_ROUTE_NM>Route 1</PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
<PRE_ROUTE_NM>Route 1</PRE_ROUTE_NM>
<VAL_ROUTE_NM>Route 1</VAL_ROUTE_NM>
</CITY>
</FIRST_BRANCH>