Получить значение из нескольких тегов xslt - PullRequest
0 голосов
/ 08 апреля 2020

Используя следующее XML

<?xml version="1.0" encoding="utf-8"?>
<Subjects>
  <Subject>
    <Title>Mr</Title>
    <Firstname></Firstname>
    <Surname></Surname>
    <Email></Email>
    <Incidents>
      <Incident>
        <ReferenceNo>meuen</ReferenceNo>
      </Incident>
    </Incidents>
    <TelephoneNos />
    <Employers />
    <BankAccounts />
  </Subject>
  <Subject>
    <Title>Mr</Title>
    <Firstname>Test</Firstname>
    <Surname>Test</Surname>
    <Email>test@test.com</Email>
    <Incidents>
      <Incident>
        <ReferenceNo>jkcsdlkjsdl</ReferenceNo>
      </Incident>
    </Incidents>
    <TelephoneNos />
    <Employers />
    <BankAccounts />
  </Subject>
</Subjects>

Я хочу извлечь все теги `` `ReferenceNo` и представить так:

<RefNos>
   <RefNo>meuen</RefNo>
   <RefNo>jkcsdlkjsdl</RefNo>
</RefNos>

Я пробовал использовать ниже XSLT:

<RefNos>
                <xsl:for-each select="(//*[local-name() ='ReferenceNo'][text()])">
                    <xsl:variable name="incidentNumbers" select="(//*[local-name() ='ReferenceNo'])"/>
                    <RefNo>
                        <xsl:value-of select="$incidentNumbers[text()]"/>
                    </RefNo>
                </xsl:for-each>
            </RefNos>

Но он получает только первый заполненный элемент в XML, если верхний тег пуст, он будет иметь значение только нижнего тега, и наоборот.

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Путь, начинающийся с //, является абсолютным путем, который выбирает всех потомков узла root документа. Таким образом, ваша переменная всегда содержит все узлы ReferenceNo во всем документе XML, независимо от текущего узла ReferenceNo. А в XSLT 1.0 инструкция xsl:value-of возвращает только значение первого узла в выбранном наборе узлов.

Если изменить переменную так, чтобы она содержала только текущий узел ReferenceNo:

<xsl:variable name="incidentNumbers" select="."/>

это будет работать так, как вы ожидаете.


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

*[local-name() ='ReferenceNo']

Кроме того, предпочтительнее использовать явные пути вместо //. Например:

<xsl:template match="/Subjects">
    <RefNos>
        <xsl:for-each select="Subject">
            <RefNo>
                <xsl:value-of select="Incidents/Incident/ReferenceNo"/>
            </RefNo>
        </xsl:for-each>
    </RefNos>
</xsl:template>

должно хорошо работать в этом случае.

1 голос
/ 08 апреля 2020

Чтобы выбрать все ReferenceNo элементы, просто используйте //ReferenceNo. Чтобы преобразовать каждый из них в элемент RefNo, используйте

<xsl:template match="/">
  <RefNos>
    <xsl:apply-templates select="//ReferenceNo"/>
  </RefNos>
</xsl:template>

<xsl:template match="ReferenceNo">
  <RefNo>
    <xsl:value-of select="."/>
  </RefNo>
</xsl:template>
...