2

我正在尝试使用 ColdFusion 的XMLValidate()函数针对ONIX XSD Schema验证 XML 文档。ONIX 是图书出版行业某些方面使用的“标准”XML 格式。

这是一个示例 XML 文档 [出于客户端 NDA 类型的原因,我修改了一些数据;对不起,长度]

<?xml version="1.0"?>
<ONIXMessage release="3.0">
  <Header>       
    <Sender>
      <SenderName>Me</SenderName>   
    </Sender>
    <SentDateTime>20131030T090000Z</SentDateTime>
    <MessageNote>My Test for SO</MessageNote>
  </Header>
  <Product>  
    <RecordReference>12345</RecordReference>     
    <NotificationType>03</NotificationType>
    <RecordSourceType>01</RecordSourceType>
    <RecordSourceName>Me</RecordSourceName>   
    <ProductIdentifier>
      <ProductIDType>15</ProductIDType>
      <IDValue>12324567801011</IDValue>
    </ProductIdentifier>
    <DescriptiveDetail>
      <ProductComposition>00</ProductComposition>
      <ProductForm>ED</ProductForm>
      <ProductFormDetail>E101</ProductFormDetail>
      <ProductFormDetail>E127</ProductFormDetail>
      <PrimaryContentType>10</PrimaryContentType>
      <EpubTechnicalProtection>01</EpubTechnicalProtection>
      <Collection>
        <CollectionType>10</CollectionType>
        <CollectionSequence>
          <CollectionSequenceType>02</CollectionSequenceType>
          <CollectionSequenceNumber>11</CollectionSequenceNumber>
        </CollectionSequence>
        <TitleDetail>
           <TitleType>01</TitleType>
           <TitleElement>
              <TitleElementLevel>02</TitleElementLevel>
              <TitlePrefix><![CDATA[The]]></TitlePrefix>
              <TitleWithoutPrefix><![CDATA[Something]]></TitleWithoutPrefix>
           </TitleElement>
        </TitleDetail>
      </Collection>    
      <TitleDetail>
        <TitleType>01</TitleType>
        <TitleElement>
          <SequenceNumber>1</SequenceNumber>
          <TitleElementLevel>01</TitleElementLevel>
          <TitleText>
            <![CDATA[ForSO]]>
          </TitleText>
        </TitleElement>
        <TitleStatement><![CDATA[The Something for SO]]></TitleStatement>
      </TitleDetail>
      <Contributor>  
        <SequenceNumber>1</SequenceNumber>
        <ContributorRole>A01</ContributorRole>
        <PersonName>Me, Myself</PersonName>
        <PersonNameInverted>Myself, Me</PersonNameInverted>
        <NamesBeforeKey>Myself</NamesBeforeKey>
        <KeyNames>Me</KeyNames>
      </Contributor>
      <Contributor>
        <SequenceNumber>2</SequenceNumber>
        <ContributorRole>A01</ContributorRole>
        <PersonName>Someone Else</PersonName>
        <PersonNameInverted>Else, Someone</PersonNameInverted>
        <NamesBeforeKey>Someone</NamesBeforeKey>
        <KeyNames>Else</KeyNames>
      </Contributor>
      <ContributorStatement>Me Myself and Someone Else</ContributorStatement>
      <Language>
        <LanguageRole>01</LanguageRole>
        <LanguageCode>eng</LanguageCode>
      </Language>
      <Extent>                              
        <ExtentType>00</ExtentType>
        <ExtentValue>40</ExtentValue>
        <ExtentUnit>03</ExtentUnit>
      </Extent>
      <Subject>
        <MainSubject/>
        <SubjectSchemeIdentifier>10</SubjectSchemeIdentifier>
        <SubjectCode>JUV001000</SubjectCode>
      </Subject>
      <Audience>
        <AudienceCodeType>01</AudienceCodeType>
        <AudienceCodeValue>02</AudienceCodeValue>
      </Audience>
      <AudienceRange>
        <AudienceRangeQualifier>17</AudienceRangeQualifier>
        <AudienceRangePrecision>03</AudienceRangePrecision>
        <AudienceRangeValue>8</AudienceRangeValue>
        <AudienceRangePrecision>04</AudienceRangePrecision>
        <AudienceRangeValue>12</AudienceRangeValue>
      </AudienceRange>
    </DescriptiveDetail>
    <CollateralDetail>
      <TextContent>
        <TextType>03</TextType>
        <ContentAudience>00</ContentAudience>
        <Text textformat="02">
          <![CDATA[Something, Something, Something, Dark Side]]>
        </Text>
      </TextContent>
    </CollateralDetail>
    <PublishingDetail>
      <Imprint>
        <ImprintName>Fake Publisher</ImprintName>
      </Imprint>
      <Publisher>
        <PublishingRole>01</PublishingRole>
        <PublisherName>Fake Publisher</PublisherName>
      </Publisher>
      <PublishingStatus>02</PublishingStatus>
      <PublishingDate>
        <PublishingDateRole>01</PublishingDateRole>
        <DateFormat>00</DateFormat>
        <Date>20110701</Date>
      </PublishingDate> 
      <SalesRights>                                  
        <SalesRightsType>02</SalesRightsType>
        <Territory>                                         
          <CountriesIncluded>GB AU NZ</CountriesIncluded>
        </Territory>
      </SalesRights>
      <SalesRestriction>
        <SalesRestrictionType>04</SalesRestrictionType>
        <SalesOutlet>
          <SalesOutletIdentifier>
            <SalesOutletIDType>03</SalesOutletIDType>
            <IDValue>AMZ</IDValue>
          </SalesOutletIdentifier>
          <SalesOutletName>Amazon</SalesOutletName>
        </SalesOutlet>
        <SalesOutlet>
          <SalesOutletIdentifier>
            <SalesOutletIDType>03</SalesOutletIDType>
            <IDValue>BNO</IDValue>
          </SalesOutletIdentifier>
          <SalesOutletName>Barnes And Noble</SalesOutletName>
        </SalesOutlet>
      </SalesRestriction>
    </PublishingDetail>
    <ProductSupply>
      <SupplyDetail>
        <Supplier>
          <SupplierRole>01</SupplierRole>
          <SupplierName>Me</SupplierName>
        </Supplier>
        <ProductAvailability>20</ProductAvailability>
        <Price>                          
          <PriceAmount>12.99</PriceAmount>
          <CurrencyCode>USD</CurrencyCode>
          <Territory>
            <CountriesIncluded>GB AU NZ</CountriesIncluded>
          </Territory>
        </Price>
      </SupplyDetail>
    </ProductSupply>
  </Product>
</ONIXMessage>  

这是一些示例代码,用于根据架构验证上述文档。要运行此代码,您必须从上面的链接下载方案并将模式文档解压缩到 Web 服务器的根目录中。将上述 XML 保存为名为 sample.xml 的文件;您可能需要修改 cffile 标记上的文件路径。

<cffile action="read" file="Sample.xml" variable="xmlFileResults" >
<Cfset xmlValidateResults = xmlValidate(xmlFileResults,'#cgi.http_host#/ONIX_BookProduct_3.0_reference.xsd') />
<cfdump var="#xmlValidateResults#" /><Br/><br/>

它提供了这个错误:

[错误]:2:28:cvc-elt.1:找不到元素“ONIXMessage”的声明。

如果我正确翻译错误,它将找不到 ONIXMessage 标记。但是,我很困惑为什么。

如果我采用更简单的 XML 文件:

<?xml version="1.0"?>
<ONIXMessage release="3.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</ONIXMessage>  

我仍然得到同样的错误。

我正在尝试确定它们是否是 XML 或 XSD 或 CFs 验证功能的错误。

有人见过这个吗?有没有人有任何见解?


根据评论,我想添加以下内容:

我不知道这是否有助于调试;但是如果我更改 XML Header 以引用它:

<ONIXMessage release="3.0" xmlns="http://ns.editeur.org/onix/3.0/reference"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://ns.editeur.org/onix/3.0/reference http://myserver/ONIX_BookProduct_3.0_reference.xsd"
            >

并从 XMLValidate() 函数中删除 XSD 引用:

<cffile action="read" file="Sample.xml" variable="xmlFileResults" >
<Cfset xmlValidateResults = xmlValidate(xmlFileResults) />
<cfdump var="#xmlValidateResults#" /><Br/><br/>

我得到了许多不同的错误,尽管它们似乎是有效的。很容易找到 ONIXMessage 的声明;但确实突出了许多其他错误。[我不确定它们是否有效]。

不幸的是,在我们的环境中,必须在 XML 文档中“硬编码”模式位置是不切实际的。

4

1 回答 1

0

我能够解决这个问题。我不得不做几件事。

首先,原始模式使用包含来包含其他文件:

<xs:include schemaLocation="ONIX_BookProduct_CodeLists.xsd"/>
<xs:include schemaLocation="ONIX_XHTML_Subset.xsd"/>

我必须删除这些包含并将这三个文件合并到一个文件中才能进行验证。我不知道验证器查找文件是否存在问题(由于本地路径)或验证例程包含的问题。创建一个不使用包含的单一模式解决了这个问题。

我还必须将架构位置添加到 XML 标头。这是原来的:

<ONIXMessage release="3.0">

这是修改后的标题:

<ONIXMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" release="3.0"
             xmlns="http://ns.editeur.org/onix/3.0/reference"  
             xsi:schemaLocation="http://ns.editeur.org/onix/3.0/reference http://mydomain.com/ONIX_BookProduct_3.0_reference.xsd">

然后验证成功——或者至少看起来是这样;我仍然遇到错误,但我觉得它们是我要验证的 XML 文档中的错误。

<cffile action="read" file="Sample.xml" variable="xmlFileResults" >
<Cfset xmlValidateResults = xmlValidate(xmlFileResults) />
<cfdump var="#xmlValidateResults#" /><Br/><br/>

为了防止更改创建文件的过程;在我们执行验证之前,我正在使用此代码“即时”将架构信息添加到标题中:

<cfset sourceString = "<ONIXMessage ([^<>]+)?>" />
<cfset replacementString = "<ONIXMessage xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" release=""3.0"" xmlns=""http://ns.editeur.org/onix/3.0/reference"" xsi:schemaLocation=""http://ns.editeur.org/onix/3.0/reference #someVaraibleWithAbsoluteURLToOnixSchema#"">" />
<Cfset fileToValidate = REReplaceNoCase(fileToValidate, sourceString, replacementString ) />

感谢这个正则表达式的答案,用于查找开始标签。

于 2013-12-13T14:22:44.060 回答