2013-03-15 2 views
2

Я знаю, что это отличается от первоначального вопроса, но это был мыслительный процесс я думал, чтобы достигнуть ниже желаемого результата:Как построить иерархическую раздел/подраздел/пункт «путь»

XML INPUT:

<section hangIndent="no" indent="arabic 1 digit" 
isProposedAmendment="no" label="2A"> 
<title>AAA</title> 
<body> 
BBB<subSection label="1"> 
    <body> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="a"> 
     <body> 
     CCC 
     </body> 
    </para> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
     isProposedAmendment="no" label="b"> 
     <body> 
     DDD 
     </body> 
    </para> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="c"> 
     <body> 
     EEE 
     </body> 
    </para> 
    </body> 
</subSection> 
</body> 
<annotation isProposedAmendment="no"> 
FFFFF 
</annotation> 
</section> 

желаемый результат: я создаю имя xmlpath на основе метки каждого узла и вставляю его в каждую конечную точку.

<nm:xmlpath name ="2A" /> 
<section hangIndent="no" indent="arabic 1 digit" 
isProposedAmendment="no" label="2A"> 
<title>AAA</title> 
<body> 
BBB 
<nm:xmlpath name ="2A 1" /> 
<subSection label="1"> 
    <body> 
    <nm:xmlpath name ="2A 1(a)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
isProposedAmendment="no" label="a"> 
     <body> 
     CCC 
     </body> 
    </para> 
    <nm:xmlpath name ="2A 1(b)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="b"> 
     <body> 
     DDD 
     </body> 
    </para> 
    <nm:xmlpath name ="2A 1(c)" /> 
    <para hangIndent="yes" indent="loweralpha 1 character" 
    isProposedAmendment="no" label="c"> 
     <body> 
     EEE 
     </body> 
    </para> 
    </body> 
</subSection> 
</body> 
<annotation isProposedAmendment="no"> 
FFFFF 
</annotation> 
</section> 
+1

Но при такой скорости ** без корневого элемента ** ваш XML может стать недействительным! Ты в порядке с этим? –

+0

@ InfantPro'Aravind 'его тестовые данные huger xml, который будет иметь корень. Благодарю. – luckyluke

+0

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

ответ

0

Основной подход будет иметь шаблон, который соответствует любому элементу, который имеет атрибут label, а до этого элемента вставить nm:xmlpath, построенный из всех label атрибутов вы найдете на родителей, бабушек и дедушек и т.д.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:nm="urn:nm-namespace"> 

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

    <xsl:template match="*[@label]"> 
    <nm:xmlpath> 
     <xsl:attribute name="name"> 
     <xsl:apply-templates select="." mode="xmlpath" /> 
     </xsl:attribute> 
    </nm:xmlpath> 
    <xsl:call-template name="identity" /> 
    </xsl:template> 

    <!-- templates to construct the xmlpath, these should produce text nodes --> 

    <!-- general case - path is the enclosing path (if any), followed by space, 
     followed by our own @label --> 
    <xsl:template match="*" mode="xmlpath"> 
    <xsl:if test="ancestor::*[@label]"> 
     <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" /> 
     <xsl:text> </xsl:text> 
    </xsl:if> 
    <xsl:value-of select="@label" /> 
    </xsl:template> 

    <!-- special case for para - no space after enclosing path, and surround 
     our label with() --> 
    <xsl:template match="para" mode="xmlpath"> 
    <xsl:apply-templates select="ancestor::*[@label][1]" mode="xmlpath" /> 
    <xsl:value-of select="concat('(', @label, ')')" /> 
    </xsl:template> 

</xsl:stylesheet> 

Для этого, чтобы сформировать правильно сформированный XML, корневой элемент вашего входного документа должен не иметь атрибут label - если бы это было сделано, мы бы попытались вставить nm:xmlpath перед этим, предоставив выходному документу два корневых файла, уровня.

0
<xsl:template match="/"> 
    <xsl:apply-templates select="//*"/> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:copy> 
    <xsl:value-of select="text()[1]"/> 
    </xsl:copy> 
</xsl:template> 

должно хватить.

+0

ОП изменил вопрос, интур изменил требование! Мне очень понравился ваш ответ, который был коротким и идеальным для более раннего требования! –

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