2016-07-01 5 views
0

Я пытаюсь проверить, содержится ли строка в наборе. У меня есть лист Excel, который я конвертирую в файл xml; Пример:XSLT проверяет, существует ли строка внутри набора

Excel лист на левый и преобразованный листе справа (RowData.xml):

ExcelXML

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

Source.xml:

<Data> 
    <Number>5556781234</Number> 
    <Number>5556781235</Number> 
    <Number>5556781236</Number> 
</Data> 

Как вы видите, он может остановиться в любом месте. Файл источника xml может иметь все номера, перечисленные в RowData.xml, или может иметь только 1 или более. Итак, мой вопрос: как я могу проверить это в моем файле xslt?

Я хочу, чтобы это сделать:

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

<!-- This is the Excel sheet converted to an XML file --> 
<xsl:param name="sheet-uri" select="'RowData.xml'"/> 
<xsl:param name="sheet-doc" select="document($sheet-uri)"/> 

<xsl:template match="Data"> 
    <xsl:for-each select="Data/Number"> 
     <xsl:variable name="continue" select="$sheet-doc//Sheet/Row[Number = current()]/Continue"/> 

     <xsl:if test=""> 
      <!-- Check the Source.xml against the RowData.xml and 
       see if the set contains any "No"'s in it. --> 

      <!-- If it does then don't do the following --> 

      <Data2> 
       <Number><xsl:value-of select="Number"/></Number> 
       <Timestamp>125222</Timestamp> 
      </Data2> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

Так в основном, прежде чем сделать <Data2> элемент, проверьте номера в Source.xml и посмотреть, если любой из этих номеров имеют значение No для столбца Continue в RowData.xml. Я не знаю, как сделать заявление if выше. Я знаю, что есть функция в xslt; однако, я не знаю, как я могу использовать его здесь.

Возможно ли это? Пожалуйста, дайте мне знать, если что-то смущает. Заранее спасибо!

ответ

1

проверить номера в Source.xml и посмотреть, имеет ли какое-либо из этих чисел значение No для столбца Продолжить в RowData.xml.

Вы можете воспользоваться «экзистенциальным равным» оператором XSLT здесь:

test="doc('source.xml')/Data/Number = 
    $sheet-doc//Sheet/Row[Continue='No']/Number" 

По существу, если А и В множестве значений, то A = B возвращает истину, если некоторое значение в А равно до некоторой величины в B.

+0

Спасибо за ответ, похоже, что он может работать! Однако есть ли другой способ написать 'doc ('source.xml')/Data/Number'? В моем коде Java я преобразовываю файл в String и анализирую его с помощью класса 'Document', а затем преобразовываю его, передавая его как' DOMSource (document) '. Например, функция 'this' будет отличной. –

+1

Вы действительно не хотите создавать DOM, если единственной причиной является преобразование XSLT. С Saxon преобразование DOM занимает в 5-10 раз больше времени, чем использование собственной модели дерева Saxon. Попробуйте переключиться на интерфейс s9api и создать дерево с помощью DocumentBuilder, а затем передать его как параметр таблицы стилей. –

+0

Я переключился на s9api, но вышеприведенное выражение 'test' продолжает возвращать' false' (То же самое с моим старым кодом). Я установил параметр через Java-код, указав путь к документу. Единственное, что я изменил в инструкции, это начальная часть: 'doc ($ source-xml) ...'. Имя параметра - '$ source-xml'. Что я делаю не так? –

1

Я предлагаю вам использовать механизм key - esp. если вы используете XSLT 2.0.

Определение ключа как:

<xsl:key name="row" match="Row" use="Number" /> 

затем сделать:

<xsl:template match="/Data"> 
    <xsl:for-each select="Number[not(key('row', ., $sheet-doc))]"> 
     <Data2> 
      <xsl:copy-of select="."/> 
      <Timestamp>125222</Timestamp> 
     </Data2> 
    </xsl:for-each> 
</xsl:template> 

Это выбирает только Number элементы, которые не имеют в RowData.xml документе соответствующего .

+0

Я не совсем понимаю ваше последнее предложение. Если я подойду к примеру, заданному в «Source.xml», оператор 'for-each' будет выбирать только теги' ', которые соответствуют номерам в' RowData.xml'? –

+0

Нет, он выбирает все остальные. Это потому, что в вашем комментарии говорится: «Если это так, не делайте следующего». Мой код говорит: * Если это не так, сделайте следующее *. –

+0

Ох хорошо. Если бы я вынул «нет», я бы получил все числа, которые соответствуют номерам в «Source.xml»? Оттуда я могу проверить, есть ли у этого набора любое * Продолжить *, что равно * Нет *? –

Смежные вопросы