문제

System.ServiceModel.Syndication에서 사용 가능한 새로운 루틴을 사용하여 RSS 및 Atom Feed를 읽기 위해 몇 가지 루틴을 작성하려고했지만 불행히도 RSS20Feedformatter는 다음과 같은 예외를 사용하여 시도하는 피드의 절반에 폭탄을 터뜨립니다.

An error was encountered when parsing a DateTime value in the XML.

RSS 피드가 게시 날짜를 다음 형식으로 표현할 때마다 발생하는 것 같습니다.

Thu, 10 월 16 일 14:23:26 -0700

피드가 게시 날짜를 GMT로 표현하면 상황이 제대로 진행됩니다.

Thu, 10 월 16 일 8 일 21:23:26 GMT

XMLReaderSettings를 사용 하여이 문제를 해결할 수있는 방법이 있다면 찾지 못했습니다. 누구든지 도울 수 있습니까?

도움이 되었습니까?

해결책

RSS 2.0 형식의 신디케이트 피드를 사용합니다 RFC 822 날짜 시간 사양 요소를 직렬화 할 때 Pubdate 그리고 Lastbuilddate. RFC 822 날짜 시간 사양은 불행히도 DateTime의 시간대 구성 요소를 표현하기위한 매우 '유연한'구문입니다.

시간대는 여러 가지 방법으로 표시 될 수 있습니다. "UT"는 보편적 인 시간입니다 (이전 "Greenwich Mean Time"이라고합니다); "GMT"는 보편적 시간에 대한 참조로 허용됩니다. 군용 표준은 각 구역에 단일 문자를 사용합니다. "Z"는 보편적 인 시간입니다. "A"는 1 시간 전에, "M"은 12 시간 전에 나타냅니다. "N"은 1 시간 후에, "Y"는 12 시간 후에입니다. 문자 "j"는 사용되지 않습니다. 나머지 두 가지 양식은 ANSI 표준 X3.51-1975에서 가져옵니다. 하나는 UT의 오프셋 금액을 명시 적으로 표시 할 수 있습니다. 다른 하나는 북미의 시간대를 나타내는 공통 3 자 문자열을 사용합니다.

나는 문제가 어떻게되는지 믿는다 RFC 822 날짜 시간 값의 구성 요소가 처리 중입니다. 피드 포맷터는 로컬 차이 시간대를 표시합니다.

RFC 1123이 RFC 822 사양을 연장하므로 DateTimeFormatInfo.rfc1123pattern ( "R") Problamatic Dateime 변환을 처리하거나 RFC 822 형식의 날짜에 대한 자신의 구문 분석 코드를 작성합니다. 또 다른 옵션은 System.ServicEmodel.syndication 네임 스페이스 클래스 대신 타사 프레임 워크를 사용하는 것입니다.

일부가있는 것 같습니다 알려진 문제 Microsoft가 해결하는 과정에서 날짜 시간 구문 분석 및 RSS20Feedformatter를 사용합니다.

다른 팁

에 게시 된 해결 방법을 기반으로합니다 이것에 대해 Microsoft에 대한 버그 보고서 비표준 날짜가있는 신디케이트 피드를 읽기 위해 특별히 XMLReader를 만들었습니다.

아래 코드는 Microsoft 사이트의 해결 방법의 코드와 약간 다릅니다. 그것은 또한 필요합니다 야당의 조언 RFC 1123 패턴을 사용합니다.

간단히 xmlreader.create ()를 호출하는 대신 스트림에서 xmlreader를 만들어야합니다. WebClient 클래스를 사용하여 해당 스트림을 얻습니다.

WebClient client = new WebClient();
using (XmlReader reader = new SyndicationFeedXmlReader(client.OpenRead(feedUrl)))
{
    SyndicationFeed feed = SyndicationFeed.Load(reader);
    ....
    //do things with the feed
    ....
}

아래는 SyndicationFeedxMlReader의 코드입니다.

public class SyndicationFeedXmlReader : XmlTextReader
{
    readonly string[] Rss20DateTimeHints = { "pubDate" };
    readonly string[] Atom10DateTimeHints = { "updated", "published", "lastBuildDate" };
    private bool isRss2DateTime = false;
    private bool isAtomDateTime = false;

    public SyndicationFeedXmlReader(Stream stream) : base(stream) { }

    public override bool IsStartElement(string localname, string ns)
    {
        isRss2DateTime = false;
        isAtomDateTime = false;

        if (Rss20DateTimeHints.Contains(localname)) isRss2DateTime = true;
        if (Atom10DateTimeHints.Contains(localname)) isAtomDateTime = true;

        return base.IsStartElement(localname, ns);
    }

    public override string ReadString()
    {
        string dateVal = base.ReadString();

        try
        {
            if (isRss2DateTime)
            {
                MethodInfo objMethod = typeof(Rss20FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Static);
                Debug.Assert(objMethod != null);
                objMethod.Invoke(null, new object[] { dateVal, this });

            }
            if (isAtomDateTime)
            {
                MethodInfo objMethod = typeof(Atom10FeedFormatter).GetMethod("DateFromString", BindingFlags.NonPublic | BindingFlags.Instance);
                Debug.Assert(objMethod != null);
                objMethod.Invoke(new Atom10FeedFormatter(), new object[] { dateVal, this });
            }
        }
        catch (TargetInvocationException)
        {
            DateTimeFormatInfo dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
            return DateTimeOffset.UtcNow.ToString(dtfi.RFC1123Pattern);
        }

        return dateVal;

    }

}

다시 말하지만, 이것은 위의 링크의 Microsoft 사이트에 게시 된 해결 방법에서 거의 정확하게 복사됩니다. ... 이것을 제외하고는 나를 위해 작동하고 Microsoft에 게시 된 것은 그렇지 않았습니다.

노트: 당신이해야 할 사용자 정의는 클래스 시작시 두 배열에 있습니다. 비표준 피드가 추가 할 수있는 외부 필드에 따라 해당 배열에 더 많은 항목을 추가해야 할 수도 있습니다.

흥미로운. DateTime 형식이 DateTime Parser가 자연스럽게 기대하는 형식 중 하나가 아닌 것처럼 보입니다. 피드 클래스를 살펴본 후에는 파서에 대한 자체 서식 규칙에 주입 할 수있는 것처럼 보이며 느낌을 검증하기 위해 특정 체계를 사용하는 것 같습니다.

DateTime Parser가 수정하여 어떻게 행동하는지 변경할 수 있습니다. 문화. 나는 전에 한 번도 해본 적이 없어서 그것이 효과가 있다고 확신 할 수 없습니다.

또 다른 해결책은 먼저 읽으려는 피드를 먼저 변형시키는 것입니다. 아마도 가장 크지는 않지만 문제를 해결할 수 있습니다.

행운을 빕니다.

.NET 4.0에서도 여전히 비슷한 문제가 지속되며 xdocument 직접 호출하는 대신 신디케이트 피드. 적용된 방법을 설명했습니다 (내 프로젝트에 따라 여기). 그것이 최상의 솔루션이라고 말할 수는 없지만, 만일을 대비하여 "백업 계획"으로 간주 될 수 있습니다. 신디케이트 피드 실패합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top