XSLT: общий или специальный тег - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь написать преобразование XML -> CSV, и я не уверен, как написать шаблон, который применяется ко всем элементам с общим синтаксисом имени, ВКЛЮЧАЯ тот, который имеет отдельный, определенный шаблон.Вот мой код:

<xsl:template match="dc:subject">
    <xsl:value-of select="replace(., '&#13;\n', '; ')"/> 
</xsl:template> 

<xsl:template match="dc:*">
   <xsl:value-of select="concat($quote, normalize-space(), $quote)" />
    <xsl:if test="following-sibling::*">
        <xsl:value-of select="$delim" />
    </xsl:if>
</xsl:template>

С преобразованием XML:

<dc:title>Title</dc:title>
<dc:subject>Dogs&#13;
Cats&#13;
Rabbits</dc:subject>
<dc:description>An adorable gathering of animals</dc:description>
<dc:date>2018 Oct 1</dc:date>

вывод в:

"Title","Dogs; Cats; Rabbits;","An adorable gathering of animals","2018 Oct 1"

Я пытался поместить это в несколькоразличные порядки, а также добавление <xsl:apply-templates match="dc:subject"> в последнем или <xsl:apply-templates match="dc:*"> в первом, но это все еще не помещает материал предмета в кавычки / с разделителем.Я знаю, что могу запутать это, просто добавив это в шаблон dc:subject, но я бы предпочел сделать это правильно, и я уверен, что это что-то довольно простое!

Заранее спасибо.

1 Ответ

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

Одним из способов использования xsl:next-match является

  <xsl:template match="dc:subject">
      <xsl:value-of select="replace(., '&#13;\n', '; ')"/>
  </xsl:template>

  <xsl:template match="dc:*" priority="2">
       <xsl:value-of select="$quote"/><xsl:next-match/><xsl:value-of select="$quote"/>
        <xsl:if test="following-sibling::*">
            <xsl:value-of select="$delim" />
        </xsl:if>
  </xsl:template>

Как видите, мне также пришлось явно повысить приоритет шаблона, выводящего кавычки, поскольку только так он будет использоваться в первую очередь.Очевидно, что для использования xsl:next-match требуется, чтобы по умолчанию существовала только текстовая копия содержимого любого dc:*, не являющегося dc:subject, но обычные таблицы стилей, встроенные правила, делают это в любом случае, так что при условии, что вы не переопределяете это в другом местевсе вышеперечисленное должно работать.

Пример в сети: https://xsltfiddle.liberty -development.net / 6qVRKwQ / 1 .

Запрос "что я хочу сделать, это применить«Один шаблон для вывода другого» возможен, только если вы используете переменную или цепочку таблиц стилей.

Я не знаю, можете ли вы быть уверены, что ваши элементы dc:* содержат один текстовый узел (и неданные, разделенные комментариями или инструкциями обработки, такими как <dc:foo>fo<!-- comment -->o</dc:foo>), но если вы уверены, что существует только один текстовый узел, тогда сопоставление элемента для вывода кавычек, например,

  <xsl:template match="dc:subject/text()">
      <xsl:value-of select="replace(., '&#13;\n', '; ')"/>
  </xsl:template>

  <xsl:template match="dc:*">
       <xsl:value-of select="$quote"/><xsl:apply-templates/><xsl:value-of select="$quote"/>
        <xsl:if test="following-sibling::*">
            <xsl:value-of select="$delim" />
        </xsl:if>
  </xsl:template>

, также возможно и нене нужно устанавливать какой-либо приоритет совпадения: https://xsltfiddle.liberty -development.net / 6qVRKwQ / 2

В обоих примерах не учитывается normalize-space(), который вы, похоже, хотите сделатьоснованный на вашем св общем, я думаю, что вы могли бы добавить <xsl:template match="dc:*/text()"><xsl:value-of select="normalize-space()"/> для обработки этого, но также потребуется использовать <xsl:value-of select="normalize-space(replace(., '&#13;\n', '; '))"/> вместо <xsl:value-of select="replace(., '&#13;\n', '; ')"/>, если текст dc:subject также нуждается в нормализации пробелов.

...