2015-09-09 4 views
0

Привет, весь этот вопрос связан с этим: xsl get element values from another node tree Но на этот раз у меня есть рабочий xslt.xslt Работа с ключами и переменными

Сейчас я работаю на следующий XML:

<record> 
    <leader>01877nz a2200433o 4500</leader> 
    <controlfield tag="001">1</controlfield> 
     ... (more controlfields tag 002 to 010) 
    <datafield tag="013" ind1=" " ind2=" "> 
    <subfield code="a">formerge</subfield> 
    </datafield> 
      ... (more datafield tags, datafield tags are from 011 to 999) 
    <datafield tag="150" ind1=" " ind2=" "> 
    <subfield code="a">Borneo</subfield> 
    </datafield> 
      ... (more datafield tags, datafield tags are from 011 to 999) 
    <datafield tag="550" ind1=" " ind2=" "> 
    <subfield code="w">g</subfield> 
    <subfield code="a">South East Asia</subfield> 
    <subfield code="c">c_7260</subfield> 
    </datafield> 
     ... (more datafield tags, datafield tags are from 011 to 999) 
    </record> 

     ... (more records) 

    <record> 
     ... (more records fields) 
     ... (more records fields) 
    </record> 

    <record> 
    <leader>02462nz a2200553o 4500</leader> 
    <controlfield tag="001">2</controlfield> 
     ... (more controlfields tag 002 to 010) 
    <datafield tag="013" ind1=" " ind2=" "> 
    <subfield code="a">formerge</subfield> 
    </datafield> 
    <datafield tag="035" ind1=" " ind2=" "> 
    <subfield code="a">c_7260</subfield> 
    </datafield> 
     ... (more datafield tags, datafield tags are from 011 to 999) 
    <datafield tag="151" ind1=" " ind2=" "> 
    <subfield code="a">South East Asia</subfield> 
    </datafield> 
     ... (more datafield tags, datafield tags are from 011 to 999) 
    </record> 

У меня есть следующий 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:key name="term" match="//datafield[@tag='151'][subfield[@code='a']]" use="." /> 

<xsl:template match="//datafield[@tag='151'][subfield[@code='a']]"> 
    <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" /> 
    <xsl:for-each select="key('term','$550a')"> 
    <xsl:value-of select="//controlfield[@tag='001']" /> 
    </xsl:for-each> 
</xsl:template> 

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

</xsl:stylesheet> 

С этим, я создал индекс всех 151 с помощью клавиш (термин) , Я также создал переменную 't550a'. Через функцию keys я сопоставляю теги 550a (поле данных tag = «550» подполе code = «a») с ключом термина. А затем получите значение тега 001 контрольного поля этого ключа. Я также хотел получить все узлы моего xml, таким образом, «xsl: copy». С xslt, который у меня есть, кажется, что тег 151 поля данных удаляется.

Я хотел бы получить в 550 поле следующее:

 ... (other fields omitted) 
<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> 
      ... (other fields omitted) 

<datafield tag="550" ind1=" " ind2=" "> 
<subfield code="w">h</subfield> 
<subfield code="a">Borneo</subfield> 
<subfield code="c">c_1017</subfield> 
<subfield code="0">1</subfield> 
</datafield> 

Так 550 подполе Южной Восточной Азии будет иметь дополнительное подполе 0 со значением 2, который основан из controlfield 001 151 подполе Южной Восточной Азии. А также подполе 550 a Borneo будет иметь дополнительное подполе 0 со значением 1, которое основано на контрольном поле 001 151 подполя a Borneo.

Может ли кто-нибудь привести меня к этому правильно. Благодаря!

ответ

1

Я думаю, что у вас есть ваш шаблон, соответствующий неправильному элементу. Если вы хотите добавить дочерний узел на поле «550», вы должны иметь соответствующий шаблон, который

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

Я также хотел бы немного изменить ключ к этому, потому что в тот момент, ключ будет с помощью пробельные узлы тоже (хотя это может быть удален, если вы использовали xsl:strip-space

<xsl:key name="term" match="datafield[@tag='151']" use="subfield[@code='a']" /> 

следующая проблема у вас есть с определением переменной tt50a. вы действительно хотите использовать относительное выражение здесь, потому что в данный момент он подберет первый соответствующий элемент в любом месте документа.Вы должны сделать это вместо (который работает, потому что вы теперь расположены на 550 узел)

<xsl:variable name="t550a" select="subfield[@code='a']" /> 

Однако представляется, что вы не на самом деле, используя эту переменную. Вы используете текущее использование ключа, key('term','$550a'), использует строковый литерал, а не переменную. Вы, наверное, имели в виду, чтобы сделать это:

<xsl:for-each select="key('term',$t550a)"> 

И, наконец, в xsl:for-each, где вы делаете //controlfield[@tag='001'] этот выбор в документе первый controlfield. Я думаю, вы только хотите выбрать тот, который находится в текущем record. Как record является родителем текущего datafield, вы можете просто сделать это:

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

Попробуйте XSLT

<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="rdf dc marc"> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
<xsl:key name="term" match="datafield[@tag='151']" use="subfield[@code='a']" /> 

<xsl:template match="datafield[@tag='550'][subfield[@code='a']]"> 
    <xsl:variable name="t550a" select="subfield[@code='a']" /> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    <xsl:for-each select="key('term',$t550a)"> 
     <subfield code="0"> 
     <xsl:value-of select="../controlfield[@tag='001']" /> 
     </subfield> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

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

Это не даст выход вы показываете в вашем вопросе точно, потому что ваш вклад XML имеет только один узел 550.

+0

Вау! Это мило Тим К., это спасло меня, пытаясь выяснить мой пешеход. Я был прав с ключами и переменной, но пока не знаю, как правильно его выполнить. И спасибо Абелю. :) – schnydszch

1

С xslt у меня есть, кажется, что тег 151 поля данных удаляется.

Да, это правильно, потому что это то, что вы поручили это сделать:

<xsl:template match="//datafield[@tag='151'][subfield[@code='a']]"> 
    <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" /> 
    <xsl:for-each select="key('term','$550a')"> 
    <xsl:value-of select="//controlfield[@tag='001']" /> 
    </xsl:for-each> 
</xsl:template> 

Это означает, что: когда datafield подобран, перебрать все термины со значением $550a и выберите (от корня!) на каждой итерации, все значения контрольного поля. Я предполагаю, что вы предпочитаете иметь контрольные поля от текущего узла, например .//controlfield....?

Но вы не создаете какой-либо элемент здесь. Если вы этого хотите, вы, вероятно, должны добавить это. I.e .:

<xsl:template match="//datafield[@tag='151'][subfield[@code='a']]"> 
    <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" /> 
    <xsl:copy> 
    <xsl:for-each select="key('term','$550a')"> 
     <xsl:value-of select="//controlfield[@tag='001']" /> 
    </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

, который скопирует datafield.

+0

Thanks Abel! Я попробовал исправленный шаблон, но, похоже, я все равно получаю то же самое. Я добавил после копирования всех узлов: \t \t \t \t \t \t schnydszch

+0

@schnydszch Если вы добавили весь шаблон соответствия, вы должны получить сообщение об ошибке. Я просто хотел обновить существующий шаблон с помощью кода выше. – Abel

+0

Предполагаю, что вы бы предпочли иметь контрольные поля из текущего узла, например .// controlfield .... Я хочу получить контрольное поле 001 из ключей, соответствующих значениям 550. Так что 550 подполей в Юго-Восточной Азии будет иметь дополнительные подполе 0 со значением 2, которое основано на контрольном поле 001 151 подполя Юго-Восточной Азии. А также подполе 550 a Borneo будет иметь дополнительное подполе 0 со значением 1, которое основано на контрольном поле 001 151 подполя a Borneo. – schnydszch

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