2010-09-13 2 views
3

Мне нужно проанализировать несколько тысяч XML-документов, чтобы увидеть, содержат ли некоторые из них определенную конструкцию. Проблема в том, что некоторые из документов не содержат хорошо сформированного XML.Проверьте, правильно ли сформирован документ перед разбором

Основная идея состояла в том, чтобы использовать fn:collection() и искать внутри возвращенных узлов. Но это работает, только если все документы в коллекции хорошо сформированы.

Можно ли сделать что-то подобное, но только разобрать хорошо сформированные документы?

Это мой XSLT, упрощен, который работает, если все документы в $dir хорошо сформированы:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xsl:output method="text"/> 
    <xsl:variable name="dir" as="xs:string">file:/c:/path/to/files/</xsl:variable> 
    <xsl:variable name="files" select="concat($dir, '?select=*.xml')" as="xs:string"/> 

    <xsl:template match="/"> 
    <xsl:variable name="docs" select="collection($files)"/> 
    <xsl:variable name="names" select=" 
     for $i in $docs return 
     distinct-values($i//*[exists(@an-attribute-to-find)]/local-name())"/> 
    <xsl:value-of select="distinct-values($names)" separator="&#x0a;"/> 
    </xsl:template> 

</xsl:stylesheet> 

Можно ли сделать что-то вроде этого не вручную сортировок НЕРАСПРОСТРАНЕНИЯ хорошо сформированных документов до начинается трансформация? Может быть, у вас есть лучшее предложение для решения?

ответ

3

В настоящее время это лучше всего сделать из XSLT.

Это можно сделать в XSLT, если вы указали в качестве параметра exrternal (<xsl:param>) преобразование список всех имен файлов, которые должны быть обработаны, - тогда преобразование будет использовать стандартную функцию XPath 2.0 doc-available() и работать только на узлах документа, возвращаемых этой функцией.

+0

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

2

Вы можете использовать TagSoup, чтобы все документы были хорошо сформированы.

Если вы используете Saxon, you can make TagSoup your parser by adding the following option:

... Вы можете использовать стандартный Saxon -x org.ccil.cowan.tagsoup.Parser вариант, убедившись, что TagSoup на вашей Java классов.

+0

TagSoup, похоже, основан на Saxon 6.5.5, который обрабатывает только XSLT 1.0. –

+0

Извините, теперь я вижу, что это также возможно использовать с XSLT 2.0, но я по-прежнему предпочитаю решение, не зависящее от других библиотек разбора. –

2

Вы можете использовать функцию doc-available, чтобы сообщить вам, правильно ли сформирован документ.

+0

Да, но проблема в том, что поскольку 'fn: collection()' собирает набор узлов, которые он разбивает во время этого вызова функции. В противном случае я мог бы использовать 'fn: doc-available()' для каждого документа. Или у вас было совершенно другое решение? :) –