2015-09-07 3 views
2

У меня есть следующие XML:XSL получить значение элементов из другого дерева узлов

<?xml version="1.0" encoding="UTF-8"?> 
<collection 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.loc.gov/MARC21/slim..." 
xmlns="http://www.loc.gov/MARC21/slim"> 

<record> 
    <leader>01877nz a2200433o 4500</leader> 
    <controlfield tag="001">1</controlfield> 
    <datafield tag="013" ind1=" " ind2=" "> 
    <subfield code="a">formerge</subfield> 
    </datafield> 
      ... 
    <datafield tag="150" ind1=" " ind2=" "> 
    <subfield code="a">Borneo</subfield> 
    </datafield> 
      ... 
    <datafield tag="550" ind1=" " ind2=" "> 
    <subfield code="w">g</subfield> 
    <subfield code="a">South East Asia</subfield> 
    <subfield code="c">c_7260</subfield> 
    </datafield> 
     ... 
    </record> 

     ... 

    <record> 
     ... 
     ... 
    </record> 

    <record> 
    <leader>02462nz a2200553o 4500</leader> 
    <controlfield tag="001">2</controlfield> 
     ... 
    <datafield tag="013" ind1=" " ind2=" "> 
    <subfield code="a">formerge</subfield> 
    </datafield> 
    <datafield tag="035" ind1=" " ind2=" "> 
    <subfield code="a">c_7260</subfield> 
    </datafield> 
     ... 
    <datafield tag="151" ind1=" " ind2=" "> 
    <subfield code="a">South East Asia</subfield> 
    </datafield> 
     ... 
    </record> 

Начиная с DataField тег = 550 с кодом узла подпола ребенка а, я хочу, чтобы добавить значение controlfield тега 001 на основе поля данных tag 151 код подполя a. В этом случае это «2». В некоторых случаях тег поля данных также может быть 150. Есть больше узлов на дереве узлов, но в основном это, как показано ниже:

<record> 
<leader>...</leader> 
<controlfield tag="001">..</controlfield> --> this one can be up to 010 
<datafield tag="150" ind1=" " ind2=" "> --> this one can be from 011 to 999 
    <subfield code="a">..</subfield> --> attributes can be 0-9, a-z 
    ... 
    </subfield> 
</datafield> 
</record>   

Так что я все еще хотел сохранить XML как раз добавлено значение, я хочу, чтобы получить, как показано ниже:

 ... 
<datafield tag="150" ind1=" " ind2=" "> 
<subfield code="a">Borneo</subfield> 
</datafield> 
      ... 
<datafield tag="550" ind1=" " ind2=" "> 
<subfield code="w">g</subfield> 
<subfield code="a">South East Asia</subfield> 
<subfield code="c">c_7260</subfield> 
<subfield code="0">2</subfield> 
</datafield> 

Возможно ли это с помощью XSLT? Может ли кто-нибудь, пожалуйста, привести меня к тому, что мне нужно прочитать? Я думаю «ключи», но может быть и другой. Заранее спасибо!

Update: У меня есть следующие шаблоны, я добавил код Абеля:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim"  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc"> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 


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

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

<xsl:variable name="next-ctl" select=" 
generate-id(
    ../controlfield[@tag = '001'] 
    /following-sibling::controlfield[1])" /> 

<xsl:template match="//datafield[@tag = '550'][subfield[@code = 'a']]"> 
<xsl:value-of select="../controlfield[@tag = '001'] 
    [following-sibling::datafield 
    [@tag = '151'] 
    [subfield[@code = 'a']] 
    [following-sibling::controlfield 
     [generate-id(.) = $next-ctl 
     or not(following-sibling::controlfield)] 
    ] 
]" /> 
</xsl:template> 

ответ

0

Это возможно даже с помощью XSLT?

Да, это предназначено для таких задач.

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

Если вы новичок в XSLT, this video tutorial by Dimitre Novatchev is a very good introduction on XSLT и сможете сэкономить много проблем. Это несколько долларов или несколько часов, потраченных очень хорошо.

Начиная с DataField теге = 550

Ie:

... с кодом узла подполе ребенка в,

Ie:

<xsl:template match="datafield[@tag = '550'][subfield[@code = 'a']]">... 

Я хочу, чтобы добавить значение controlfield тега 001

И.Э., предполагая фокус от предыдущего шаблона соответствия:

<xsl:value-of select="../controlfield[@tag = '001']" /> 

на основе DataField тег 151 кода подполе в.

Поскольку datafield элементов кажутся сибсами controlfield (я предполагаю, что каждый controlfield сопровождается набором полей данных), я буду считать, что они должны быть среди следующих братий и сестер, но до следующего controlfield, но настроить к вашим потребностям.

Ie:

<xsl:variable name="next-ctl" select=" 
    generate-id(
     ../controlfield[@tag = '001'] 
     /following-sibling::controlfield[1])" /> 

<xsl:value-of select=" 
    ../controlfield[@tag = '001'] 
    [following-sibling::datafield 
     [@tag = '151'] 
     [subfield[@code = 'a']] 
     [following-sibling::controlfield 
      [generate-id(.) = $next-ctl 
      or not(following-sibling::controlfield)] 
     ] 
    ]" /> 

Примечание: если выражения становятся сложными, как эти, и упрощение не является тривиальным (т.е. разделение и использование переменных), вы можете рассмотреть вопрос о переходе на XSLT 2.0, что позволяет большую свободу выражения, комментарии внутри внутренних выражений (т. е. так называемые смайлики-комментарии, (:...:)) и имеет больше способов проверки (в данном случае, например, если один элемент лежит перед другим в порядке документа: и >> операторов).

В этом случае это «2».

Выше код не проверен (ваши требования слишком сложны, и я боюсь, что не понимаю их), но это, вероятно, что-то в этом роде.

В некоторых случаях тег поля данных в соответствии с ним также может быть 150.

В каких случаях вы должны соответствующим образом отрегулировать.

Я думаю «ключи», но может быть и другой.

Да, это может помочь, но это зависит от остальных требований, это действительно необходимо (см. Примеры выше).

+0

Hi Abel, теги контрольного поля вводятся только в первых строках сразу после лидера. И да поля данных - это братья и сестры с контрольным полем. И в отношении значений, которые я хочу получить, я хочу вставить в тег 550 подполе 0, которое является тегом контрольного поля 001 тега 150 или 151 поля данных. Это 150 или 151 имеет то же значение с тегом 550. А также деревья узлов могут быть в другом месте, а не последовательно или следуют друг за другом. – schnydszch

+0

@schnydszch, тогда мои предложения должны указывать на вас в правильном направлении, хотя может потребоваться некоторая настройка. Они независимо от порядка, в котором они появляются. – Abel

+0

Привет, Абель. Я добавил ваш ответ после копирования всех шаблонов. Возможно, я что-то пропустил. ТИА! – schnydszch

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