2015-09-07 79 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> 

从数据字段标签= 550开始与子节点子字段代码,我要根据数据字段添加controlfield标签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> 

回答

0

这甚至可能使用XSLT?

是的,它是用于这样的任务。

请问有人能带我到我需要读的东西吗?

如果您是XSLT的新手,this video tutorial by Dimitre Novatchev is a very good introduction on XSLT并且会为您节省很多麻烦。这花了几美元或几个小时。

从数据字段标签开始= 550

即:

...与子节点子字段代码,

即:

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

我想补充controlfield标签001

即价值,假设对焦距离为前一个匹配的模板:

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

基于数据域标记151子代码。

由于datafield元素似乎controlfield(我假设每个controlfield后面是一组数据域的),我将承担他们必须跻身以下的兄弟姐妹兄弟姐妹,但接下来的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,它允许表达更自由, (即所谓的笑脸评论,(:...:)),并有更多的测试方法(在这种情况下,例如,如果一个元素在文档顺序中位于另一个之前:<<>>运算符)。

在这种情况下,它是“2”。

上面的代码未经过测试(您的要求太复杂,我担心我会误解它们),但它可能是沿着这些方向的。

在某些情况下,要匹配的数据字段标记也可以是150。

在哪些情况下,您应该相应地进行调整。

我在想“钥匙”,但可能会有另一个。

是的,这可能有帮助,但它取决于其余的要求是这实际上是需要的(见上面的例子)。

+0

嗨阿贝尔,控制字段标签只在领导之后的第一行输入。数据字段是控制字段的兄弟。关于我想要得到的值,我想在标签550中插入一个子字段0,它是数据字段标签150或151的控制字段001标签。这个150或151与550标签具有相同的值。而且节点树可以在其他地方,而不是顺序或彼此跟随。 – schnydszch

+0

@schnydszch然后我的建议应该指出你在正确的方向,但它可能需要一些调整。无论它们出现的顺序如何。 – Abel

+0

嗨亚伯我复制所有模板后添加了你的答案。我可能会错过一些东西。 TIA! – schnydszch