Java: 转义 XML 文本内容而不是整个文本
Java: Escape XML text content instead of entire text
我想发送下面的 XML 请求。应转义文本内容,但不转义标签。
我试过使用下面的转义逻辑。
String str = escapeXml11(req);
但是,我的整个请求都被转义了。所以,它不再有效 XML.
我的原字符串:
String req =
"<request>\r\n"
+ " <Products>\r\n"
+ " <Product>\r\n"
+ " <ProductName>H < M</ProductName>\r\n"
+ " <quantity>1</quantity>\r\n"
+ " <totalProductCost>17.03</totalProductCost>\r\n"
+ " </Product>\r\n"
+ " </Products>\r\n"
+ "</request>";
转义后:
<request>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</request>
预期结果:
<request>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</request>
如何只转义文本内容?
所以这个问题的根源是第3方提供给你的"XML"格式不正确
<request>
<Products>
<Product>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</Product>
</Products>
</request>
要更正此问题,您需要将 "H < M"
转换为 "H < M"
。人类很容易做到这一点,如果人类必须做很多这样的事情,模精度就会出现问题。但是自动化很难。
显然,简单地调用转义方法是行不通的。如果不解析 XML,转义方法无法确定需要转义的内容。 (像 escapeXml11
这样的方法只有在需要转义整个字符串时才有效。)
普通的 XML 解析器会看到 "< M"
尝试将其视为元素标记的开始。然后它会看到下一个 "<"
... 和错误。要进一步进行,它必须回溯到 "< M"
并将 "<"
视为已转义 .
我知道有一个 HTML / XML 解析器 (JSoup) 可以处理错位的 "<"
字符。但是,如果我理解正确,它会以错误的方式处理您的用例。与其将 "< M"
视为数据,不如将其转换为开始标记:
<request>
<Products>
<Product>
<ProductName>H <M></ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</Product>
</Products>
</request>
剩下两个选择:
您可以尝试使用一些模式匹配来检测和修复问题。例如,如果您知道格式错误的数据在 <ProductName>...</ProductName>
元素中,那么您可以使用正则表达式搜索这些元素,检查并(如有必要)更正内容,然后替换它。
您可以使用上下文相关的词法分析器为您的 XML 编写自定义解析器。当解析器看到 <ProductName>
时,它会将词法分析器切换到另一种模式,将“<
”视为数据 ,除非 它是 [=24= 的开始].
但是在你去写一堆自定义代码来处理这个无效的时间和费用之前XML:
向创建它的第 3 方投诉。他们不应该像那样排放垃圾。他们的软件或数据收集/清理存在缺陷。他们应该修复它。
确保支付软件开发和维护费用的人知道这一点。例如,如果您签约编写一些处理 XML 的软件,这不是 XML。如果客户没有警告您您的软件需要处理格式错误的 XML,那是需求变更,可能(应该)是合同的 变体 .
另请参阅@Michael Kay 的评论。
这是我在到处寻找解决方案后发现的:
获取 Jsoup 库:
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
然后:
Document doc = Jsoup.parse(new ByteArrayInputStream(YOUR_XML_STRING_HERE.getBytes("UTF-8")), "UTF-8", "", Parser.xmlParser())
doc.outputSettings().charset("UTF-8")
doc.outputSettings().escapeMode(Entities.EscapeMode.base)
println doc.toString()
希望这对某人有所帮助
我想发送下面的 XML 请求。应转义文本内容,但不转义标签。
我试过使用下面的转义逻辑。
String str = escapeXml11(req);
但是,我的整个请求都被转义了。所以,它不再有效 XML.
我的原字符串:
String req =
"<request>\r\n"
+ " <Products>\r\n"
+ " <Product>\r\n"
+ " <ProductName>H < M</ProductName>\r\n"
+ " <quantity>1</quantity>\r\n"
+ " <totalProductCost>17.03</totalProductCost>\r\n"
+ " </Product>\r\n"
+ " </Products>\r\n"
+ "</request>";
转义后:
<request>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</request>
预期结果:
<request>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</request>
如何只转义文本内容?
所以这个问题的根源是第3方提供给你的"XML"格式不正确
<request>
<Products>
<Product>
<ProductName>H < M</ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</Product>
</Products>
</request>
要更正此问题,您需要将 "H < M"
转换为 "H < M"
。人类很容易做到这一点,如果人类必须做很多这样的事情,模精度就会出现问题。但是自动化很难。
显然,简单地调用转义方法是行不通的。如果不解析 XML,转义方法无法确定需要转义的内容。 (像 escapeXml11
这样的方法只有在需要转义整个字符串时才有效。)
普通的 XML 解析器会看到 "< M"
尝试将其视为元素标记的开始。然后它会看到下一个 "<"
... 和错误。要进一步进行,它必须回溯到 "< M"
并将 "<"
视为已转义 .
我知道有一个 HTML / XML 解析器 (JSoup) 可以处理错位的 "<"
字符。但是,如果我理解正确,它会以错误的方式处理您的用例。与其将 "< M"
视为数据,不如将其转换为开始标记:
<request>
<Products>
<Product>
<ProductName>H <M></ProductName>
<quantity>1</quantity>
<totalProductCost>17.03</totalProductCost>
</Product>
</Products>
</request>
剩下两个选择:
您可以尝试使用一些模式匹配来检测和修复问题。例如,如果您知道格式错误的数据在
<ProductName>...</ProductName>
元素中,那么您可以使用正则表达式搜索这些元素,检查并(如有必要)更正内容,然后替换它。您可以使用上下文相关的词法分析器为您的 XML 编写自定义解析器。当解析器看到
<ProductName>
时,它会将词法分析器切换到另一种模式,将“<
”视为数据 ,除非 它是 [=24= 的开始].
但是在你去写一堆自定义代码来处理这个无效的时间和费用之前XML:
向创建它的第 3 方投诉。他们不应该像那样排放垃圾。他们的软件或数据收集/清理存在缺陷。他们应该修复它。
确保支付软件开发和维护费用的人知道这一点。例如,如果您签约编写一些处理 XML 的软件,这不是 XML。如果客户没有警告您您的软件需要处理格式错误的 XML,那是需求变更,可能(应该)是合同的 变体 .
另请参阅@Michael Kay 的评论。
这是我在到处寻找解决方案后发现的:
获取 Jsoup 库:
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
然后:
Document doc = Jsoup.parse(new ByteArrayInputStream(YOUR_XML_STRING_HERE.getBytes("UTF-8")), "UTF-8", "", Parser.xmlParser())
doc.outputSettings().charset("UTF-8")
doc.outputSettings().escapeMode(Entities.EscapeMode.base)
println doc.toString()
希望这对某人有所帮助