使用xsd文件对对象的值进行动态验证

使用xsd文件对对象的值进行动态验证

xsd动态验证对象值

以前做了一个项目,挺有意思的,业务需求经常变动。业务方提出要求,希望我们对保存的对象的值,在不改动代码的情况下,能通过配置验证的条件。思索一下,那不就是通过配置文件来进行控制吗?不就像我们编写mybaitis、spring文件一样,可以通过xsd来控制我们输入。

干就完了

1、先定义一个值对象

@XmlRootElement(name = "B2CReq")  **//对应test.xsd的 <xs:element name="B2CReq">**
public class B2CReq {
    @XmlElement
    public String merId; **//对应test.xsd的 <xs:element name="merId">**
    @XmlElement
    public String orderNo;**//对应test.xsd的 <xs:element name="orderNo">**
    @XmlElement
    public String orderAmt;**//对应test.xsd的 <xs:element name="orderAmt">**

    @XmlTransient
    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    @XmlTransient
    public String getOrderAmt() {
        return orderAmt;
    }

    public void setOrderAmt(String orderAmt) {
        this.orderAmt = orderAmt;
    }

    @XmlTransient
    public String getMerId() {
        return merId;
    }

    public void setMerId(String merId) {
        this.merId = merId;
    }
}

2、编写一个xsd文件test.xsd,用于控制验证

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
<xs:element name="B2CReq">
    <xs:complexType>
      <xs:all>
		<xs:element name="merId">
			<xs:simpleType>
			  <xs:restriction base="xs:string">
				<xs:minLength value="1"/>
				<xs:maxLength value="20"/>
			  </xs:restriction>
			</xs:simpleType>
		</xs:element>
 
		<xs:element name="orderNo">
			<xs:simpleType>
			  <xs:restriction base="xs:string">
				<xs:minLength value="1"/>
				<xs:maxLength value="30"/>
			  </xs:restriction>
			</xs:simpleType>
		</xs:element>
 
		<xs:element name="orderAmt">
			<xs:simpleType>
			  <xs:restriction base="xs:decimal">
				<xs:pattern value="[\d]{0,16}\.[\d]{2}"/>
			  </xs:restriction>
			</xs:simpleType>
		</xs:element>

      </xs:all>
    </xs:complexType>
</xs:element>
 
</xs:schema>

3、一个类,用于读取xsd配置,来验证输入的对象值验证

public class XmlUtils {
    private static XmlUtils instance = null;
    public static XmlUtils getInstance(){
        if(instance==null){
            instance = new XmlUtils();
        }
        return instance;
    }

    public <T> String objToXml(T t) throws Exception{
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_ENCODING,"utf-8");
        StringWriter sw = new StringWriter();
        m.marshal(t,sw);
        return sw.toString();
    }

    public <T> boolean validate(T t, String schemaFile) throws Exception{
        JAXBContext context = JAXBContext.newInstance(t.getClass());
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
        Schema schema = factory.newSchema(new File(schemaFile));
        Marshaller m = context.createMarshaller();
        m.setSchema(schema);
        m.marshal(t, new DefaultHandler());
        return true;
    }
}

4、测试

    public static void main(String[] args) {
        B2CReq bq = new B2CReq();
        bq.setMerId("s");
        bq.setOrderNo("s");
        bq.setOrderAmt("1.00");
        try {
           boolean s = XmlUtils.getInstance().validate(bq, "/test.xsd");
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

测试一结果为:true

    public static void main(String[] args) {
        B2CReq bq = new B2CReq();
        bq.setMerId("s");
        bq.setOrderNo("s");
        bq.setOrderAmt("1.011");
        try {
           boolean s = XmlUtils.getInstance().validate(bq, "/test.xsd");
            System.out.println(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

测试二结果为:抛出如下异常,表示1.011超过了小数点后面2位,所以不符合。
javax.xml.bind.MarshalException

  • with linked exception:
    [org.xml.sax.SAXParseException; lineNumber: 0; columnNumber: 0; cvc-pattern-valid: 对于类型为 ‘#AnonType_orderAmtB2CReq’ 的模式 ‘[\d]{0,16}.[\d]{2}’, 值 ‘1.011’ 不具有面有效性。]
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:123)
    at com.freespace.xmlxsdvalidate.XmlUtils.validate(XmlUtils.java:39)

大家感兴趣可以多谢几个测试用例进行测试。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在 C++ 中使用 XSD 文件检测 XML 需要用到第三方库,比如 Xerces-C++。下面是使用 Xerces-C++ 库检测 XML 的步骤: 1. 安装 Xerces-C++ 库并包含其头文件。 2. 创建 XSD 文件,定义 XML 文档的结构和约束。 3. 创建 XML 文档并加载到内存中。 4. 创建 Xerces-C++ 的 DOM 解析器,并设置解析器的验证属性。 5. 创建 Xerces-C++ 的 DOM 文档对象,并将 XML 文档加载到该对象中。 6. 创建 Xerces-C++ 的 DOM 文档类型对象,并将 XSD 文件加载到该对象中。 7. 使用解析器解析 XML 文档,并将 XSD 文件作为第二个参数传递给解析器的 parse 方法。 8. 如果 XML 文档符合 XSD 文件中定义的约束,则它是有效的 XML 文档。如果不符合,则会出现错误或警告。 以下是使用 Xerces-C++ 库检测 XML 的示例代码: ``` #include <xercesc/dom/DOM.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/util/XMLUni.hpp> #include <xercesc/framework/LocalFileInputSource.hpp> #include <iostream> using namespace xercesc; using namespace std; int main(int argc, char* argv[]) { try { XMLPlatformUtils::Initialize(); // 加载 XML 文档 XercesDOMParser parser; parser.parse("example.xml"); // 创建 DOM 文档对象 DOMDocument* doc = parser.getDocument(); // 创建 DOM 文档类型对象 DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(XMLString::transcode("Core")); DOMDocumentType* type = impl->createDocumentType( XMLString::transcode("example"), XMLString::transcode("example.dtd"), XMLString::transcode("example.sys") ); // 创建解析器并设置验证属性 parser.setDoValidation(true); parser.setDoSchema(true); parser.setValidationSchemaFullChecking(true); // 解析 XML 文档并检测约束 parser.parse("example.xml"); if(parser.getErrorCount() == 0) { cout << "XML is valid." << endl; } else { cout << "XML is not valid." << endl; } XMLPlatformUtils::Terminate(); } catch(const XMLException& e) { cerr << "Error: " << XMLString::transcode(e.getMessage()) << endl; return 1; } return 0; } ``` 在此示例中,example.xml 是要验证的 XML 文档的名称,example.dtd 是 XSD 文件的名称。如果 XML 文档符合 XSD 文件中定义的约束,则输出 "XML is valid.",否则输出 "XML is not valid."。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值