5

編集- 私は自分の問題の解決策を見つけ出し、ここにQ&Aを投稿しました。

米国議会図書館のEAD標準(ここにあります)に準拠したXMLを処理しようとしています。残念ながら、XMLの構造に関しては標準が非常に緩いです。

たとえば、タグは、タグ内、タグ<bioghist>内に存在するか、別のタグ内にネストされるか、または上記の組み合わせであるか、完全に省略される可能性があります。他のタグも選択せずに、探しているバイオギストタグだけを選択するのは非常に難しいことがわかりました。<archdesc><descgrp><bioghist>

以下は、XSLTが処理しなければならない可能性のあるいくつかの異なるEADXMLドキュメントです。

最初の例

<ead>
<eadheader>
    <archdesc>
        <bioghist>one</bioghist>
        <dsc>
            <c01>
                <descgrp>
                    <bioghist>two</bioghist>
                </descgrp>
                <c02>
                    <descgrp>
                        <bioghist>
                            <bioghist>three</bioghist>
                        </bioghist>
                    </descgrp>
                </c02>
            </c01>
        </dsc>
    </archdesc>
</eadheader>
</ead>

2番目の例

<ead>
<eadheader>
    <archdesc>
        <descgrp>
            <bioghist>
                <bioghist>one</bioghist>
            </bioghist>
        </descgrp>
        <dsc>
            <c01>
                <c02>
                    <descgrp>
                        <bioghist>three</bioghist>
                    </descgrp>
                </c02>
                <bioghist>two</bioghist>
            </c01>
        </dsc>
    </archdesc>
</eadheader>
</ead>

3番目の例

<ead>
<eadheader>
    <archdesc>
        <descgrp>
            <bioghist>one</bioghist>
        </descgrp>
        <dsc>
            <c01>
                <c02>
                    <bioghist>three</bioghist>
                </c02>
            </c01>
        </dsc>
    </archdesc>
</eadheader>
</ead>

ご覧のとおり、EADXMLファイルには<bioghist>ほとんどどこにでもタグが付いている可能性があります。私が生成すると思われる実際の出力は、ここに投稿するには複雑すぎます。上記の3つのEADの例の出力の簡略化された例は、次のようになります。

最初の例の出力

<records>
<primary_record>
    <biography_history>first</biography_history>
</primary_record>
<child_record>
    <biography_history>second</biography_history>
</child_record>
<granchild_record>
    <biography_history>third</biography_history>
</granchild_record>
</records>

2番目の例の出力

<records>
<primary_record>
    <biography_history>first</biography_history>
</primary_record>
<child_record>
    <biography_history>second</biography_history>
</child_record>
<granchild_record>
    <biography_history>third</biography_history>
</granchild_record>
</records>

3番目の例の出力

<records>
<primary_record>
    <biography_history>first</biography_history>
</primary_record>
<child_record>
    <biography_history></biography_history>
</child_record>
<granchild_record>
    <biography_history>third</biography_history>
</granchild_record>
</records>

「最初の」bioghist値を取得して、それをに入れたい場合、そのタグはタグの直接の子孫ではない可能性があるため、<primary_record>単純にはできません。それは、またはそれらの組み合わせによって包まれる可能性があります。そして、それはすべてのタグを引っ張るので、私はできません。実際にはタグがない可能性があるため、できません。その後、「Second」であり、後で処理する必要がある値を下にプルします。<xsl:apply-templates select="/ead/eadheader/archdesc/bioghist"<archdesc><descgrp><bioghist>select="//bioghist"<bioghist>select="//bioghist[1]"<bioghist><c01>

<cxx>これはすでに長い投稿ですが、もう1つの問題は、最大12レベルの深さまでネストされたノードの数に制限がないことです。現在、再帰的に処理しています。現在処理しているノード(<c01>たとえば)を「RN」という変数として保存してから、を実行してみ<xsl:apply-templates select=".//bioghist [name(..)=name($RN) or name(../..)=name($RN)]">ました。<bioghist>これは、タグがあまり深くネストされていない一部の形式のEADで機能しますが、タグを他のタグでラップするのが大好きな人が作成したEADファイルを処理する必要がある場合は失敗します(EADによると完全に問題ありません)。標準)。

私が好きなのはどういうわけか言うことです

  • 現在のノードの下の任意の<bioghist>タグを取得しますが、
  • <c??>タグをヒットした場合は深く掘らないでください

状況を明確にしたことを願っています。あいまいな点があれば教えてください。あなたが提供できるどんな援助も大いにありがたいです。ありがとう。

4

2 に答える 2

2

要件はかなりあいまいであるため、回答は作成者が行った推測のみを反映しています。

これが私のものです:

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

 <my:names>
  <n>primary_record</n>
  <n>child_record</n>
  <n>grandchild_record</n>
 </my:names>

 <xsl:variable name="vNames" select="document('')/*/my:names/*"/>

 <xsl:template match="/">
  <xsl:apply-templates select=
   "//bioghist[following-sibling::node()[1]
                                [self::descgrp]
              ]"/>
 </xsl:template>

 <xsl:template match="bioghist">
  <xsl:variable name="vPos" select="position()"/>

  <xsl:element name="{$vNames[position() = $vPos]}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<ead>
    <eadheader>
        <archdesc>
            <bioghist>first</bioghist>
            <descgrp>
                <bioghist>first</bioghist>
                <bioghist>
                    <bioghist>first</bioghist></bioghist>
            </descgrp>
            <dsc>
                <c01>
                    <bioghist>second</bioghist>
                    <descgrp>
                        <bioghist>second</bioghist>
                        <bioghist>
                            <bioghist>second</bioghist></bioghist>
                    </descgrp>
                    <c02>
                        <bioghist>third</bioghist>
                        <descgrp>
                            <bioghist>third</bioghist>
                            <bioghist>
                                <bioghist>third</bioghist></bioghist>
                        </descgrp>
                    </c02>
                </c01>
            </dsc>
        </archdesc>
    </eadheader>
</ead>

必要な結果が生成されます:

<primary_record>first</primary_record>
<child_record>second</child_record>
<grandchild_record>third</grandchild_record>
于 2012-06-28T03:39:44.127 に答える
0

ソリューションは特定のXML標準に非常に固有であり、この質問の範囲外であると思われたため、私は自分でソリューションを作成し、このQ&Aに投稿しました。ここにも投稿するのがベストだと思われる場合は、この回答をコピーで更新できます。

于 2012-07-11T18:38:08.697 に答える