2015-01-04 2 views
0

Я новичок в кодирование XSL, здесь я пытаюсь взять весь блок (результата) узлов и размещение внутри другого узла под названием РЕЗУЛЬТАТОВ ... Ниже мой xml и xsl.скопировать весь блок под другим узел - преобразования XSLT

Но это не преобразование XML, как ожидалось ...

Может кто-нибудь мне помочь, когда я делаю это неправильно?

XML

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="samplexslt.xsl"?> 
<report> 
<Header> 
<RegNo>123</RegNo> 
<EmrNo>op2145</EmrNo> 
<BillNo>opcb1234-12</BillNo> 
<Uhid>1209</Uhid> 
<AdmissionDate>13-Jan-2014</AdmissionDate> 
</Header> 

<result> 
<name>test1</name> 
<desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
<desc2>description</desc2> 
</result> 
<result> 
<name>test2</name> 
<desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
</result> 

<Footer> 
<DoctorSign>Anand</DoctorSign> 
</Footer> 
</report> 

XSLT

<?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" omit-xml-declaration="yes"/> 
<xsl:template match="/report"> 
<xsl:copy> 
<xsl:apply-templates select="@*|node()[local-name() != 'result']"/> 
</xsl:copy> 
<notes> 
<xsl:apply-templates select="result" /> 
</notes> 
</xsl:template> 

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

Ожидаемое

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="samplexslt.xsl"?> 
<report> 
<Header> 
<RegNo>123</RegNo> 
<EmrNo>op2145</EmrNo> 
<BillNo>opcb1234-12</BillNo> 
<Uhid>1209</Uhid> 
<AdmissionDate>13-Jan-2014</AdmissionDate> 
</Header> 

<results>  
<result> 
    <name>test1</name> 
    <desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
    <desc2>description</desc2> 
</result> 
<result> 
    <name>test2</name> 
    <desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
</result> 
</results> 

<Footer> 
<DoctorSign>Anand</DoctorSign> 
</Footer> 
</report> 
+1

Зачем стоит отмечать 'XSLT 2.0'? Ваша таблица стилей объявляет 'version =" 1.0 "'. –

ответ

2

Вы можете переместить все result блоки в качестве дополнительного results блока так:

<?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" omit-xml-declaration="yes"/> 
<xsl:strip-space elements="*"/> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="result"> 
    <results> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
     <xsl:apply-templates select="following::result" mode="copy"/> 
    </results> 
    </xsl:template> 
    <xsl:template match="result[preceding-sibling::result]"/> 
    <xsl:template match="result" mode="copy"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

выход, когда применяются к вашей входной XML:

<report> 
<Header> 
    <RegNo>123</RegNo> 
    <EmrNo>op2145</EmrNo> 
    <BillNo>opcb1234-12</BillNo> 
    <Uhid>1209</Uhid> 
    <AdmissionDate>13-Jan-2014</AdmissionDate> 
    </Header> 
    <results> 
    <result> 
    <name>test1</name> 
    <desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
    <desc2>description</desc2> 
    </result> 
    <result> 
    <name>test2</name> 
    <desc1>abcdefghijklmnopqrstuvwxyz</desc1> 
    </result> 
    </results> 
    <Footer> 
    <DoctorSign>Anand</DoctorSign> 
    </Footer> 
</report> 

Пустой шаблон <xsl:template match="result[preceding-sibling::result]"/> матчей всех результирующие узлы, которые предыдущие результат узлы, так что <xsl:template match="result"> матчи только первый результат.
В этом шаблоне, с помощью

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

копии первого результата, а затем применяет шаблон с mode="copy" для всех следующих результатов:

<xsl:apply-templates select="following::result" mode="copy"/> 

Это <xsl:template match="result" mode="copy"> просто копирует все следующие result узлы внутри нового results блока ,

Обратите внимание, что этот подход, хотя и работает, может быть чрезмерным. Если ваш входной XML содержит только известный заголовок, результат и нижний колонтитул, я рекомендую просто использовать XSLT, предоставленный в подробном ответе, заданном michael.hor257k.

+2

Если возможно, не могли бы вы дать небольшое объяснение о коде, который вы предоставили? – Thavudu

+3

@Thavudu Конечно, но из-за того, что я уже объяснил все шаблоны, которые я использовал (кроме преобразования идентичности, которое вы уже используете в коде в своем вопросе), не могли бы вы дать некоторые подробности, что я должен объяснить дальше? Это также поможет мне улучшить ответы. –

0

Может ли кто-нибудь помочь мне, где я делаю это неправильно?

Основная проблема (есть несколько) с вашим подходом является то, что вы поместили инструкцию:

<notes> 
    <xsl:apply-templates select="result" /> 
</notes> 

за пределы <xsl:copy> блока - и, следовательно, вне report элемента в целом. Вы должны поместить его внутри, и - если вы хотите, чтобы результаты шли между заголовком и нижним колонтитулом, вы должны применять к ним шаблоны отдельно.

Кроме того, если вы хотите, чтобы результаты были помещены «внутри другого узла под названием РЕЗУЛЬТАТЫ», то не поместить их внутрь notes.

Обратите внимание, что XML с учетом регистра: RESULTS - это не то же самое, что и results, отображаемое в ожидаемом выводе.

Попробуй так:

XSLT 1,0

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

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

<xsl:template match="/report"> 
    <xsl:copy> 
     <xsl:apply-templates select="Header"/> 
     <results> 
      <xsl:apply-templates select="result" /> 
     </results> 
     <xsl:apply-templates select="Footer" /> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Конечно, если это все ваша таблица стилей делает, вы можете уменьшить его:

XSLT 1.0

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

<xsl:template match="/report"> 
    <xsl:copy> 
     <xsl:copy-of select="Header"/> 
     <results> 
      <xsl:copy-of select="result" /> 
     </results> 
     <xsl:copy-of select="Footer" /> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
Смежные вопросы