Сравнение двух значений с доступом к предкам - PullRequest
0 голосов
/ 21 сентября 2018

Мне нужно посмотреть в моем XML значение той же ссылки, и из этого сравнения я должен найти и получить данные предков.XML выглядит следующим образом:

<Section version="1" subversion="1" key="xy://data/Section/42df2def-b485-4600-9701-a9a0cb3fb0ba/?language=de-DE">
    <Heading>This is a heading</Heading>
    <Sequence version="1" subversion="1" key="xy://data/Sequence/70533309-defa-46af-a419-56e134ed0757/"> 
        <Target>How to do ABC</Target>
        <Step StepId="id12345">
            <Condition>
                <Para>First step.</Para>
                <Para>Do ... to get ...</Para>
            </Condition>
        </Step>
        <Step>
            <Condition>
                <Para>Second step.</Para>
                <Para>Reference: <StepRef StepIdRef="id12345"/></Para>
            </Condition>
        </Step>
    </Sequence>
</Section>

<Section version="1" subversion="1" key="xy://data/c2e4fa40-372e-4fe7-a63d-a73848c8f28b/?language=de-DE">
    <Heading>This is another heading</Heading>
    <Sequence version="1" subversion="1" key="27329b6b-95ef-4959-af95-f04f99391005/">
        <Target>How to do XYZ</Target>
        <Step>
            <Condition>
                <Para>Important step, see <StepRef StepIdRef="id12345"/></Para>
            </Condition>
        </Step>
    </Sequence>
</Section>

То, что я хочу, должно выглядеть следующим образом:

<a href="" my.id="{key from Sequence}" my.version="{version from Sequence}" my.type="{name of object type}" fragment="{stepId_version_type}"/>

В моем случае оба примера должны выглядеть следующим образом:

<p>Reference: <a href="" my.id="70533309-defa-46af-a419-56e134ed0757" my.version="1" my.type="Sequence" fragment="id12345_1_Sequence"/>
<p>Important step, see <a href="" my.id="70533309-defa-46af-a419-56e134ed0757" my.version="1" my.type="Sequence" fragment="id12345_1_Sequence"/>

И мой XSLT выглядит так:

<xsl:template match="StepRef">
    <xsl:param name="catchStep" select="StepIdRef">
        <xsl:if test="$catchStep=//@StepId">
            <a>
                <xsl:attribute name="href"/>

                <!-- To get the stepId -->
                <xsl:attribute name="my.id"><xsl:value-of select="ancestor::*[@key]/substring-before(substring-after(substring-after(@key, 'data/'), '/'), '/')"/></xsl:attribtue>
                <!-- To get the version -->
                <xsl:attribute name="my.version"><xsl:value-of select="ancestor::*[@key]/@version"/></xsl:attribtue>
                <!-- To get the object type -->
                <xsl:attribute name="my.type"><xsl:value-of select="ancestor-or-self::*[@key]/substring-before(substring-after(@key, 'data/'), '/')"/></xsl:attribtue>

                <xsl:attribute name="fragment">
                    <!-- To get the stepId -->
                    <xsl:value-of select="$firstStep"/>
                    <xsl:text>_</xsl:text>
                    <!-- To get the version -->
                    <xsl:value-of select="ancestor::*[@key]/@version"/>
                    <xsl:text>_</xsl:text>
                    <!-- To get the object type -->
                    <xsl:value-of select="ancestor::*[key]/substring-before(substring-after(@key, 'data/'), '/')"/>
                </xsl:attribute>
            </a>
        </xsl:if>
</xsl:template>

Основные проблемы:

  • Почему-то я всегда ловлю Секцию вместо Последовательности (и получаюсоответствующие данные)
  • Похоже, что это работает только для шагов в той же теме
  • Я не знаю, как я могу получить доступ к той же переменной и сделать мои элементы управления XPath оттуда
  • Я не думаю, что мой XSLT правильно закодирован

1 Ответ

0 голосов
/ 21 сентября 2018

Похоже, что вы могли бы сделать с помощью xsl:key здесь, чтобы найти шаги

Так что, если вы находитесь в шаблоне, соответствующем StepRef, вы можете посмотретьпошаговый шаг, выполнив key('Steps', @StepIdRef) (и чтобы получить родителя, выполните key('Steps', @StepIdRef)..).

Вы можете еще больше упростить свой код, используя Шаблоны значений атрибутов , чтобы упростить создание атрибутов.

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

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="Steps" match="Step" use="@StepId" />

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

  <xsl:template match="StepRef">
    <xsl:variable name="object" select="key('Steps', @StepIdRef)/.." />
    <a href="" 
        my.id="{substring-before(substring-after(substring-after($object/@key, 'data/'), '/'), '/')}" 
        my.version="{$object/@version}" 
        my.type="{local-name($object)}"
        fragment="{@StepIdRef}_{$object/@version}_{local-name($object)}"/>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...