Почему мой xslt выбирает дочерний узел узла, который я не указал? - PullRequest
0 голосов
/ 11 октября 2018

Раньше я использовал xslt несколько лет назад, и хотя я не был экспертом, я мог писать базовые преобразования.У меня сейчас проблемы, которых я не понимаю.

Здесь я пытаюсь извлечь запись Dublin Core из записи foxml.Запись Dublin Core в xml, а foxml - это в основном стандарт xml, который группирует множество записей xml.

Вот мой xml:

    <?xml version="1.0" encoding="UTF-8"?>
<foxml:digitalObject VERSION="1.1" PID="vital:26113"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<foxml:objectProperties>
    <foxml:property NAME="info:fedora/fedora-system:def/model#state" VALUE="Active"/>
    <foxml:property NAME="info:fedora/fedora-system:def/model#label" VALUE="DCity/DCCPC_DC.xml"/>
    <foxml:property NAME="info:fedora/fedora-system:def/model#ownerId" VALUE=""/>
    <foxml:property NAME="info:fedora/fedora-system:def/model#createdDate"
        VALUE="2016-09-06T19:49:51.257Z"/>
    <foxml:property NAME="info:fedora/fedora-system:def/view#lastModifiedDate"
        VALUE="2016-09-27T13:23:10.950Z"/>
    <foxml:extproperty NAME="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" VALUE="FedoraObject"/>
    <foxml:extproperty NAME="info:fedora/fedora-system:def/model#contentModel" VALUE=""/>
</foxml:objectProperties>
<foxml:datastream ID="DC" STATE="A" CONTROL_GROUP="X" VERSIONABLE="true">
    <foxml:datastreamVersion ID="DC.0" LABEL="Dublin Core for this Record"
        CREATED="2016-09-06T19:49:51.290Z" MIMETYPE="text/xml"
        FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
        <foxml:xmlContent>
            <oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
                xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
                <dc:title>St. Patricks</dc:title>
                <dc:creator>Mary Mooney</dc:creator>
                <dc:publisher>Publisher</dc:publisher>
                <dc:format>Photograph</dc:format>
                <dc:identifier>123456</dc:identifier>
                <dc:identifier>100.jpg</dc:identifier>
                <dc:coverage>1984</dc:coverage>
                <dc:rights>Publisher</dc:rights>
            </oai_dc:dc>
        </foxml:xmlContent>
    </foxml:datastreamVersion>
    <foxml:datastreamVersion ID="DC.1" LABEL="Dublin Core for this Record"
        CREATED="2016-09-27T13:23:10.894Z" MIMETYPE="text/xml"
        FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
        <foxml:xmlContent>
            <oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
                <dc:title>St Audoen&apos;s</dc:title>
                <dc:creator>William Mooney</dc:creator>
                <dc:publisher>Publisher</dc:publisher>
                <dc:format>Photograph</dc:format>
                <dc:identifier>10987654</dc:identifier>
                <dc:identifier>200.jpg</dc:identifier>
                <dc:coverage>1984</dc:coverage>
                <dc:rights>Publisher</dc:rights>
            </oai_dc:dc>
        </foxml:xmlContent>
    </foxml:datastreamVersion>
</foxml:datastream>
</foxml:digitalObject>

, а вот мой xslt

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
    <xsl:output method="xml" indent="yes" name="xml"/>
   <xsl:template match="/foxml:digitalObject/foxml:datastreamVersion[@ID eq DC.1]/foxml:xmlContent">
       <metadata>
         <xsl:value-of select="oai_dc:dc"/>
               <xsl:copy-of select="."/>
            </metadata>
        </xsl:template>
    </xsl:stylesheet>

Я ожидаю, что будет возвращена секция DC в foxml: datastreamVersion с ID = DC.1.Вместо этого я получаю следующее:

<?xml version="1.0" encoding="UTF-8"?>

                St. Patricks
                Mary Mooney
                Publisher
                Photograph
                123456
                100.jpg
                1984
                Publisher


                St Audoen's
                William Mooney
                Publisher
                Photograph
                10987654
                200.jpg
                1984
                Publisher

Итак, у меня есть две очевидные проблемы:

  1. почему он выбирает материал из узла, который не соответствует атрибуту Iвыбрал?

  2. почему он возвращает только текст, а не теги сопровождающих элементов и т. д.?

Я использую oXygen 19.1 сSaxon-EE.9.7.0.19 трансформатор.

1 Ответ

0 голосов
/ 11 октября 2018

Во-первых, у вас проблема с выражением соответствия, должно быть это ...

 /foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent

Вы пропустили foxml:datastream в пути.Также «DC.1» нужно было поставить в апострофах, чтобы сделать его строкой, в отличие от имени элемента.

Однако, в ответ на ваш вопрос «почему он выбирает материал из узла, который не 'не соответствует атрибуту ", ответ" Из-за встроенных шаблонов XSLT"

Когда XSLT начинает свою обработку, он будет искать шаблон, соответствующий узлу документа /.У вас нет такого шаблона в вашем XSLT, и поэтому шаблон по умолчанию включается. По сути, это эквивалентно наличию этих двух шаблонов в вашем XSLT

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

Они пропускают элементы, но выводят текст там, где находятэто, что приводит к выводу всего другого текста.Чтобы прекратить это, добавьте этот шаблон к вашему XSLT

<xsl:template match="node()">
  <xsl:apply-templates />
</xsl:template>

(В XSLT 3.0 вместо этого введите <xsl:mode on-no-match="shallow-skip" />)

Что касается второго вопроса, когда шаблон соответствует, вы делаете<xsl:value-of select="oai_dc:dc"/> и выводит все нисходящие текстовые узлы.Вместо этого следует использовать xsl:copy-of.

Попробуйте это XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
    exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
    version="2"
    xmlns:foxml="info:fedora/fedora-system:def/foxml#"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">

  <xsl:output method="xml" indent="yes" name="xml"/>

  <xsl:template match="node()">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="/foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent">
    <metadata>
      <xsl:copy-of select="oai_dc:dc"/>
    </metadata>
  </xsl:template>
</xsl:stylesheet>

В качестве альтернативы, просто сопоставьте узел документа и выберите целевой объект, который вы хотите скопировать, с помощью выбора.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
    exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
    version="2"
    xmlns:foxml="info:fedora/fedora-system:def/foxml#"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">

  <xsl:output method="xml" indent="yes" name="xml"/>

  <xsl:template match="/">
    <xsl:apply-templates select="foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent" />
  </xsl:template>

  <xsl:template match="foxml:xmlContent">
    <metadata>
      <xsl:copy-of select="oai_dc:dc"/>
    </metadata>
  </xsl:template>
</xsl:stylesheet>
...