xsl получает значения элемента из другого дерева узлов

У меня есть следующий XML:

<?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>

Начиная с тега поля данных =550 с кодом подполя дочернего узла a, я хочу добавить значение тега 001 поля управления на основе кода подполя тега 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? Может кто-нибудь привести меня к тому, что мне нужно прочитать? Я думаю о "ключах", но может быть и другой. Заранее спасибо!

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

<?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>

1 ответ

Это возможно даже с XSLT?

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

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

Если вы новичок в XSLT, это видеоурок от Dimitre Novatchev очень хорошее введение в XSLT и избавит вас от многих проблем. Это несколько долларов или несколько часов, проведенных очень хорошо.

Начиная с тега поля данных =550

То есть:

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

... с кодом подполя дочернего узла a,

То есть:

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

Я хочу добавить значение тега контрольного поля 001

Т.е., предполагая, что фокус от предыдущего соответствующего шаблона:

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

на основе тега поля данных 151 код подполя а.

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

То есть:

<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, который обеспечивает большую свободу выражения, комментарии внутри выражений (то есть так называемые smiley-comments, (:...:)) и имеет больше способов для проверки (в этом случае, например, если один элемент лежит перед другим в порядке документа: << а также >> операторы).

В данном случае это "2".

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

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

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

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

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

Другие вопросы по тегам