Использование XSLT в качестве препроцессора XML - PullRequest
2 голосов
/ 26 августа 2011

Это мой первый раз, когда я что-то делаю с XSLT или XML, поэтому, пожалуйста, извините.Я обнаружил, что веб-документация XSLT действительно лаконична.

У меня есть файл XML, который я хочу обработать, чтобы выборочно отбрасывать контент на основе входного набора определений.Поведение должно быть аналогично простому препроцессору кода, обрабатывающему блоки ifdef.

Я разработал, как это сделать, как показано ниже, но некоторые части, такие как переменная "содержимого", не выглядят каклучший способ справиться с этим.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" />
  <xsl:param name="defines-uri" required="yes"/>

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

  <xsl:template match="ifdef">
    <xsl:variable name="contents" select="child::node()"/>
    <xsl:variable name="defines" select="document($defines-uri)/defines"/>
    <xsl:variable name="val" select="@select"/>

    <xsl:for-each select="$defines">
      <xsl:if test="def=$val">
        <xsl:apply-templates select="$contents"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

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

Каков наилучший способ предварительной обработки XML без преобразования?

Ответы [ 2 ]

1 голос
/ 26 августа 2011

Вы хорошо справляетесь с теми, кто только начинает с XSLT и XML.

Это не ответ на ваш вопрос, но я просто хотел сказать, что это может быть более безопасный шаблон «Копировать по умолчанию»:

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

Ваш работает из-за определенного встроенного шаблона по умолчанию. Но вы можете получить странное поведение в отношении текстовых узлов (или других вещей, которые не являются элементами), когда вы добавляете больше шаблонов, поскольку значение по умолчанию имеет низкий приоритет.

1 голос
/ 26 августа 2011

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

Хорошов основном вы поняли это правильно.Вы все еще можете его немного улучшить:

<xsl:variable name="defines" select="document($defines-uri)/defines"/>

<xsl:template match="ifdef">
  <xsl:variable name="this" select="."/>

  <xsl:for-each select="$defines[def = $this/@select]">
    <xsl:apply-templates select="$this/node()" />
  </xsl:for-each>
</xsl:template>

<xsl:for-each> изменяет узел контекста.Внутри него . относится к узлу, который итерируется, а не к тому, который был сопоставлен <xsl:template>.

Это означает, что вы должны сохранить «внешний» контекст в переменной, этоэто стандартная практика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...