2014-02-18 1 views
1

Как скопировать некоторые атрибуты из узла. Для примера. Я хочу скопировать только «Srno», «RollNo», «right» из узла «Extn».XSL: копирование Как скопировать некоторые атрибуты из узла?

<Main> 
    <SubMainLevel1 material="12" feature="range"> 
    <SubMainLevel2 arg1="abc" arg2="123"> 
     <Item name="hello" desc="one" /> 
     <Detail long="high" short="wide" /> 
     <Extn Srno="12" RollNo="12" weight="12" folds="2" right="Y" left="N" top="T" bottom="V" /> 
    </SubMainLevel2> 
    <SubMainLevel2 arg1="cyz" arg2="123"> 
     <Item name="hello2" desc="two" /> 
     <Detail long="short" short="wide" /> 
     <Extn Srno="" RollNo="" weight="" folds="1" right="Y" left="N" top="T" bottom="V" /> 
    </SubMainLevel2> 
    </SubMainLevel1> 
</Main> 

Xsl Я использую выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:strip-space elements="*" /> 
    <xsl:template match="/"> 
     <Job> 
     <xsl:copy-of select="Main/SubMainLevel1/@*[name()='material']" /> 
     <Lines> 
      <xsl:for-each select="/Main/SubMainLevel1/SubMainLevel2"> 
       <xsl:if test="@arg2 = '123'"> 
        <Line> 
        <xsl:copy-of select="@*" /> 
        <xsl:copy-of select="node()[name() = 'Item']" /> 
        <xsl:copy-of select="node()[name() = 'Detail']" /> 
        <xsl:copy-of select="node()[name() = 'Extn']" /> 
        </Line> 
       </xsl:if> 
      </xsl:for-each> 
     </Lines> 
     </Job> 
    </xsl:template> 
</xsl:stylesheet> 

Вот как я могу ограничить узел «Внутр» с упомянутым только выше значений.

Ожидаемый результат является

<?xml version="1.0" encoding="UTF-8"?> 
<Job material="12"> 
    <Lines> 
     <Line arg1="abc" arg2="123"> 
     <Item name="hello" desc="one" /> 
     <Detail long="high" short="wide" /> 
     <Extn Srno="12" RollNo="12" right="Y"/> 
     </Line> 
     <Line arg1="cyz" arg2="123"> 
     <Item name="hello2" desc="two" /> 
     <Detail long="short" short="wide" /> 
     <Extn Srno="" RollNo="" right="Y"/> 
     </Line> 
    </Lines> 
</Job> 

Примечание: Это не то же самое, как «How not to copy some attributes?»

+1

Не могли бы мы видеть, что должен делать вывод? –

+0

Куда вы хотите скопировать код * к этому вопросу. – Tomalak

+0

Почему '@ * [name() = 'material']'? Это отличается от '@ материала'? –

ответ

3

Я думаю, что вы могли бы извлечь выгоду от использования identity template здесь

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

Это означает, что вместо того, чтобы писать это ....

<Line> 
     <xsl:copy-of select="@*" /> 
     <xsl:copy-of select="node()[name() = 'Item']" /> 
     <xsl:copy-of select="node()[name() = 'Detail']" /> 
     <xsl:copy-of select="node()[name() = 'Extn']" /> 
    </Line> 

Вы можете написать эту

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

Тогда вы просто шаблон, соответствующий Внутр, когда вы можете выбрать атрибуты, которые вы хотите

<xsl:template match="Extn"> 
    <xsl:copy> 
     <xsl:apply-templates select="@Srno|@RollNo|@right|node()"/> 
    </xsl:copy> 
</xsl:template> 

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

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

    <xsl:template match="Main"> 
     <Job> 
     <xsl:copy-of select="SubMainLevel1/@*[name()='material']" /> 
     <Lines> 
      <xsl:apply-templates select="SubMainLevel1/SubMainLevel2[@arg2 = '123']" /> 
     </Lines> 
     </Job> 
    </xsl:template> 

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

    <xsl:template match="Extn"> 
     <xsl:copy> 
     <xsl:apply-templates select="@Srno|@RollNo|@right|node()"/> 
     </xsl:copy> 
    </xsl:template> 

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

Примечание Я использую сопоставление шаблонов на SubMainLevel2 здесь, вместо XSL: для-каждого, а также обратите внимание, как нет необходимости в XSL: если, как условие может идти как часть выражения select.

+0

Это работает как ожидалось. Прочтите объяснение – 2FaceMan

1

Я считаю, что это будет делать то, что вы хотите (в несколько более простым способом, чем то, что у вас есть сейчас) :

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

<xsl:template match="/"> 
    <Job material="{Main/SubMainLevel1/@material}"> 
     <Lines> 
      <xsl:for-each select="Main/SubMainLevel1/SubMainLevel2[@arg2=123]"> 
       <Line> 
        <xsl:copy-of select="@* | Item | Detail" /> 
        <Extn Srno="{Extn/@Srno}" RollNo="{Extn/@RollNo}" right="{Extn/@right}" /> 
       </Line> 
      </xsl:for-each> 
     </Lines> 
    </Job> 
</xsl:template> 

</xsl:stylesheet> 
+0

Предоставление некоторой ошибки. Работать отлично, если я просто беру '' из вашего xsl – 2FaceMan

+0

Работает отлично для меня - см. Здесь: http://xsltransform.net/948Fn5e Какой процессор вы используете и какая именно ошибка вы получаете? –

+0

Я попробовал [здесь] (http://xslttest.appspot.com/) – 2FaceMan

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