Фильтрация атрибутов xsl: value-of - PullRequest
0 голосов
/ 16 декабря 2009

У меня есть XML-документ, подобный этому:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="./transform.xsl"?>
<Documentation><Tables>
<TABLE TABLE_NAME="FirstTable">
  <COLUMN COLUMN_NAME="FirstColumn" ORDINAL_POSITION="1" IS_NULLABLE="NO" DATA_TYPE="int" />
  <COLUMN COLUMN_NAME="SecondColumn" ORDINAL_POSITION="2" IS_NULLABLE="NO" DATA_TYPE="int" />
</TABLE>

...

</Tables><Comments>
<COMMENT ForTable="FirstTable" ForColumn="FirstColumn">Description of FirstColumn</COMMENT>
</Comments></Documentation>

Мой вопрос: как получить значение COMMENT при циклическом просмотре таблиц и столбцов? У меня есть:

<xsl:for-each select="//TABLE">
  ...
  <xsl:for-each select="COLUMN">
    ...
    <xsl:value-of select="//COMMENT[@ForTable = @TABLE_NAME and @ForColumn=@COLUMN_NAME]" />

Но это не работает. Любой совет?

Ответы [ 2 ]

2 голосов
/ 16 декабря 2009

Это не работает, потому что значение select выбирает «получить значение всех комментариев, атрибут ForTable которых имеет то же значение, что и их атрибут TABLE NAME, а атрибут ForColumn имеет то же значение, что и их атрибут COLUMN NAME».

Попробуйте что-то вроде

<xsl:for-each select="//TABLE">
    <xsl:variable name="table_name" select="@TABLE_NAME"/>
    ...
    <xsl:for-each select="COLUMN">
        <xsl:variable name="column_name" select="@COLUMN_NAME"/>
        ...
        <xsl:value-of select="//COMMENT[@ForTable=$table_name and @ForColumn=$column_name]" />
1 голос
/ 16 декабря 2009

Другой вариант решения этой проблемы:

<xsl:for-each select="/Documentation/Tables/TABLE">
  <!-- select all comments for the current table name… -->
  <xsl:variable name="$comments" select="
    /Documentation/Comments/COMMENT[@ForTable = current()/@TABLE_NAME]
  "/>

  <xsl:for-each select="COLUMN">
    <!-- …of those, select the one with the current column name -->
    <xsl:value-of select="
      $comments[@ForColumn = current()/@COLUMN_NAME]
    " />
  </xsl:for-each>
</xsl:for-each>

Преимущества:

  • вам нужна только одна переменная вместо двух
  • внутренний for-each может работать быстрее, так как он ищет меньший, предварительно отфильтрованный набор данных

Обратите внимание, что:

  • Я использую current() для ссылки на узел контекста XSLT в предикатах XPath.
  • Я избегаю // в выражениях XPath, поскольку он имеет очень плохие характеристики производительности и не должен использоваться, если это возможно. Исходная структура документа подразумевает, что // не требуется.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...